How to get 3 conditions in laravel - laravel

guys so I want to get 3 conditions in controller Laravel, So I build a post with the comment system. My comment has 3 conditions, from default condition it will get value = 0, when is approved it will get value = 1, when it's denied it will give value = 2. I want to get 3 conditions to count how many it is because I want to build another value like value = 3 or 4 or 5 for another condition so I won't use get all.
Here is my comment controller function code
private function getCountComment()
{
$user = Auth::user();
$comcount = $user->competitions;
foreach ($comcount as $key => $value) {
$count = Comment::where('id_post', $value->id)
->where('is_accepted', '=', 0 AND 1 AND 3)
->count();
$comcount[$key]->comment_to_count = $count;
}
return $comcount;
}
I try that code but only get the first condition is_accepted = 0.
Hope you guys can help me.

Try this code
private function getCountComment(){
$user = Auth::user();
$comcount = $user->competitions;
foreach ($comcount as $key => $value) {
$comcount[$key]->comment_to_count = Comment::where('id_post', $value->id)->whereIn('is_accepted', [0,1,3])->count();
}
return $comcount;
}
or you can
Comment::where('id_post', $value->id)->where(function($query) {
$query->where('is_accepted', '=', 0)
->orWhere('is_accepted', '=', 1)
->orWhere('is_accepted', '=', 3)
})->count();

Related

Eloquent query builder get only items which have child items

So I am trying to get a list of all active clients that have active jobs but I'm at a loss of how to accomplish this. So here is what I have...
$query = Client::select( 'clients.*' )->where( 'is_enabled', 1 )->activeJobs();
Which throws an error
Call to undefined method Illuminate\Database\Eloquent\Builder::activeJobs()
in my client model i have the activeJobs() function as follows:
public function activeJobs()
{
return $this->hasMany( Job::class )->where( 'is_active', 1 );
}
Just to explain what I am after with my query in words, I'm trying to get a collection of all active client items (determined by is_enabled = 1) which have 1 or more active jobs (determined by is_active = 1)
thanks
What you are looking for is has/whereHas.
So, what you should do is
$query = Client::select('clients.*')
->whereHas('jobs', fn($query) => $query->where('is_active', 1))
->where('is_enabled', 1)
->get();
This will return you a collection of Clients whose Job's is_active column is 1
Try this
$query = Client::select('clients.*')
->where('is_enabled', 1)
->whereHas('activeJobs', function ($query) {
$query->where('is_active', 1);
})
->get();
Try this
$query = Client::has('activeJobs', '>', 1)->get();
Try This:
$query = Client::with('activeJobs')->select( 'clients.*' )->where( 'is_enabled', 1 );
This will return the clients with their relationship(Active Jobs), what you are doing in the code is trying to grab relationship data from collection..
You can either grab the clients, then foreach $client->activeJobs;
or use with which wil return it in query level.
Get active jobs and then collect related users:
$cliensWithActiveJobs = Job::with('client')
->where('is_active', 1)
->get(['id', 'client_id'])
->map(fn ($job) => $job->client)
->unique('id');

Saving Array ID to Database with value to each id

Good Evening.... Hope i can explain my problem correctly.
I am getting data (ID) in array and value (numbers) in controller. Now i want to save the "numbers" in each "ID".
array ID ["Buffalo-01", "Buffalo-02", "Buffalo-04"]
Numbers - 40.
Want to save 40 to each ID.
Controller
public function addbuffalototalmilk(Request $req )
{
$buffalomilking = Buffalodata::where('avgmilk','<>','0')->Where('status','=','Available')->count(); // MIlking Animal Nos
$getbuffalomilkingid = Buffalodata::where('avgmilk','<>','0')->Where('status','=','Available')->pluck('buffaloID'); // Get Buffalo Details of Milking
$totalmorningmilk = $req->get('morningtotalmilk');
$totaleveningmilk = $req->get('eveningtotalmilk');
$eachmorningmilk = ($totalmorningmilk / $buffalomilking);
$eacheveningmilk = ($totaleveningmilk / $buffalomilking);
return response ();
}
Thanks in Advance
Is this what you are looking for ?
$buffalomilking = Buffalodata::where('avgmilk', '<>', '0')
->Where('status', '=', 'Available')
->count();
$getbuffalomilkingid = Buffalodata::where('avgmilk', '<>', '0')
->Where('status', '=', 'Available')
->pluck('buffaloID');
foreach ($getbuffalomilkingid as $id) {
Buffalodata::where('id', $id)->update([
'number' => $buffalomilking,
]);
}

Count giving wrong amount in laravel

I'm trying to get the amount of items I have based on what I have in my rank column. So if I have 3 items that has a rank of high then I want it to show 3 and if I have a rank of low and it has 2 items I need it to show 2.
But the issue I'm having is that it's counting all my items so I'm getting a count of 5.
Here is my code
$items = Item::all();
foreach($items as $item)
{
if($item->rank === 'high')
{
$count = $item->count();
dd($count);
}
}
You can use filter collection:
$items = Item::all();
$highRank = $items->filter(function ($value, $key) {
return $value->rank == 'high';
});
$highRank->count();
More detail with this collection check this doc: https://laravel.com/docs/8.x/collections#method-filter
You can use group by rank and get the count
$Items = Item::select('rank', DB::raw('count(*) as total'))
->groupBy('rank')
->get();
simple used
$items = Item::where('rank','high')->get()->count();

OctoberCMS - Model query with relation manyToMany

Once again i'm asking some help from the community...
Scenario:
I have two tables with one pivot table (something like posts and tags to give some context):
table 1 (Evento):
-id
-....
table 2 (Etiquetas):
-id
-etiqueta
pivot table (Eventos_Etiquetas):
-evento_id (pk)
-etiqueta_id (pk)
The relations are set as:
public $belongsToMany = [
'eventos' => ['JML\Gkb\Models\Evento', 'table' => 'jml_gkb_eventos_etiquetas']
];
and
public $belongsToMany = [
'etiquetas' => ['JML\Gkb\Models\Etiqueta', 'table' => 'jml_gkb_eventos_etiquetas']
];
Now, what i want to achieve:
-get all events that have any individual tag without regarding the order of input (or).
-get all events that have all tags without regarding the order of input (and).
As you can imagine i'm strugling with this as i'm new to October/Laravel query builder (and not so to sql).
What i've done so far:
if (Session::get('tipo') == 'etiqueta'){
$pesquisa = preg_split('/\s+/', $temp, -1, PREG_SPLIT_NO_EMPTY);
if (Session::get('modo') == 0){
$this['records'] = Evento::with('etiquetas')->whereHas('etiquetas', function($query) use ($pesquisa){
foreach ($pesquisa as $palavra){
$query->where('etiqueta', 'like', "%$palavra%");
}
})->orderBy('id', 'DESC')->paginate(25);
}
if (Session::get('modo') == 1){
$this['records'] = Evento::with('etiquetas')->whereHas('etiquetas', function($query) use ($pesquisa){
foreach ($pesquisa as $palavra){
$query->orWhere('etiqueta', 'like', "%$palavra%");
}
})->orderBy('id', 'DESC')->paginate(25);
}
}
The user input is passed by $temp variable and it's splited to words to the $pesquisa array variable. 'modo' defines if the user pretend a search by AND (0) or by OR (1). Based on that choice a query is built to try to get the results using $palavra variable as any word of $pesquisa.
The result of this:
In modo == 0, i only can get the events of one tag of user input, if it have more than one word (any letter that don't exist on first word) don't get any result.
In modo == 1 it gets all events.
In both cases i don't get any event that don't have any tag (etiqueta) - correct behaviour.
I've tried some other ways but with no avail... This one looks to me the most logical of the tries... Can someone point me on the correct direction ?
TIA
JL
After some tries i have half of the problem solved. The part where i want to get any "Evento" that has any of the "Etiqueta" on user input not regarding the order of them is working fine finally.
Resume bellow
if (Session::get('tipo') == 'etiqueta'){
$pesquisa = preg_split('/\s+/', $temp, -1, PREG_SPLIT_NO_EMPTY);
$cadeiapesquisa = implode('|', $pesquisa);
/***** NOT WORKING YET *****/
if (Session::get('modo') == 0){
$this['records'] = Evento::with('etiquetas')->whereHas('etiquetas', function($query) use ($pesquisa){
foreach ($pesquisa as $palavra){
$query->where('etiqueta', 'like', "%$palavra%");
}
})->orderBy('id', 'DESC')->paginate(25);
}
/****** THIS IS WORKING FINE ! *******/
if (Session::get('modo') == 1){
if ( count ($pesquisa) > 0 && !($temp == null)){
$this['records'] = Evento::with('etiquetas')->whereHas('etiquetas', function($query) use ($cadeiapesquisa){
$query->where('etiqueta', 'regexp', "$cadeiapesquisa");
})->orderBy('id', 'DESC')->paginate(25);
} else {
Evento::paginate(25);
}
}
}
The first parte is fighting, but i will get there. :)
TIA
JL
[EDIT]
Problem solved... The resulting snipet of code working so far with the tests i've done is bellow:
if (Session::get('tipo') == 'etiqueta'){
$pesquisa = preg_split('/\s+/', $temp, -1, PREG_SPLIT_NO_EMPTY);
$cadeiapesquisa = implode('|', $pesquisa);
$contagem = count($pesquisa);
if (Session::get('modo') == 0){
if ( strlen($cadeiapesquisa) > 0 ){
$this['records'] = Evento::with('etiquetas')->whereHas('etiquetas', function($query) use ($cadeiapesquisa, $contagem){
$query->where('etiqueta', 'regexp', "$cadeiapesquisa")->groupBy('evento_id')->having(DB::raw("COUNT('etiqueta_id')"), '>=', $contagem );
})->paginate(25);
} else {
$this['records'] = Evento::paginate(25);
}
}
if (Session::get('modo') == 1){
if ( strlen($cadeiapesquisa) > 0 ){
$this['records'] = Evento::with('etiquetas')->whereHas('etiquetas', function($query) use ($cadeiapesquisa){
$query->where('etiqueta', 'regexp', "$cadeiapesquisa");
})->paginate(25);
} else {
$this['records'] = Evento::paginate(25);
}
}
}
JL

Laravel how do I get the row number of an object using Eloquent?

I'd like to know the position of a user based on its creation date. How do I do that using Eloquent?
I'd like to be able to do something like this:
User::getRowNumber($user_obj);
I suppose you want MySQL solution, so you can do this:
DB::statement(DB::raw('set #row:=0'));
User::selectRaw('*, #row:=#row+1 as row')->get();
// returns all users with ordinal 'row'
So you could implement something like this:
public function scopeWithRowNumber($query, $column = 'created_at', $order = 'asc')
{
DB::statement(DB::raw('set #row=0'));
$sub = static::selectRaw('*, #row:=#row+1 as row')
->orderBy($column, $order)->toSql();
$query->remember(1)->from(DB::raw("({$sub}) as sub"));
}
public function getRowNumber($column = 'created_at', $order = 'asc')
{
$order = ($order == 'asc') ? 'asc' : 'desc';
$key = "userRow.{$this->id}.{$column}.{$order}";
if (Cache::get($key)) return Cache::get($key);
$row = $this->withRowNumber($column, $order)
->where($column, '<=',$this->$column)
->whereId($this->id)->pluck('row');
Cache::put($key, $row);
return $row;
}
This needs to select all the rows from the table till the one you are looking for is found, then selects only that particular row number.
It will let you do this:
$user = User::find(15);
$user->getRowNumber(); // as default ordered by created_at ascending
$user->getRowNumber('username'); // check order for another column
$user->getRowNumber('updated_at', 'desc'); // different combination of column and order
// and utilizing the scope:
User::withRowNumber()->take(20)->get(); // returns collection with additional property 'row' for each user
As this scope requires raw statement setting #row to 0 everytime, we use caching for 1 minute to avoid unnecessary queries.
$query = \DB::table(\DB::raw('Products, (SELECT #row := 0) r'));
$query = $query->select(
\DB::raw('#row := #row + 1 AS SrNo'),
'ProductID',
'ProductName',
'Description',
\DB::raw('IFNULL(ProductImage,"") AS ProductImage')
);
// where clauses
if(...){
$query = $query->where('ProductID', ...));
}
// orderby clauses
// ...
// $query = $query->orderBy('..','DESC');
// count clause
$TotalRecordCount = $query->count();
$results = $query
->take(...)
->skip(...)
->get();
I believe you could use Raw Expresssions to achieve this:
$users = DB::table('users')
->select(DB::raw('ROW_NUMBER() OVER(ORDER BY ID DESC) AS Row, status'))
->where('status', '<>', 1)
->groupBy('status')
->get();
However, looking trough the source code looks like you could achieve the same when using SQLServer and offset. The sources indicates that if you something like the following:
$users = DB::table('users')->skip(10)->take(5)->get();
The generated SQL query will include the row_number over statement.
[For Postgres]
In your model
public function scopeWithRowNumber($query, $column = 'id', $order = 'asc'){
$sub = static::selectRaw('*, row_number() OVER () as row_number')
->orderBy($column, $order)
->toSql();
$query->from(DB::raw("({$sub}) as sub"));
}
In your controller
$user = User::withRowNumber()->get();

Resources