How to filter a Laravel collection - laravel

I have to following eloquent db statements in my function. Two read statements on the db.
$groups = V_Member::where('groupadmin', '=', Auth::id())->get();
$members = V_Member::where([['idgroup', $groupid],['groupadmin', Auth::id()]])->get();
First I want to execude the first db statement and then I want to filter on the collection/variable.
Like this below. But I get an error. What I have to change?
$groups = V_Member::where('groupadmin', '=', Auth::id())->get();
$members = $groups::where(['idgroup', '=', $groupid])->get();
This is the error message
Non-static method Illuminate\Support\Collection::where() should not be called statically

You can just use:
$members = $groups->where('idgroup', $groupid);
Operator= is not necessary but you can use it where you want. You can also take a look at where method documentation.

If you want to filter the collection instead of running 2 queries, then you will just need to change:
$members = $groups::where(['idgroup', '=', $groupid])->get();
to:
$members = $groups->where('idgroup', '=', $groupid);
For more information you can have a look at the documentation

Since $groups is a collection and not a Model Class...
You should use ->where() instead of ::where()
Don't confuse collections with eloquent querys, it's a common mistake.
Also, don't confuse methods for building querys with eloquent, with methods for collections, another common mistake.

Related

Laravel 7 Query with() and using Where()

Hey guys I have a query that looks like this
$query = Transaction::with(['customer', 'merchant', 'batch'])
->select(sprintf('%s.*', (new Transaction)->table));
I need to filter the transaction based on the iso_id that belons to the current user logged in.
$query = Transaction::with(['customer', 'merchant', 'batch'])
->select(sprintf('%s.*', (new Transaction)->table))
->where('merchant.iso_id', '=', auth()->user()->isIso());
The iso_id I need to compare to, is inside the merchant table
auth()->user()->isIso() returns the correct iso_id if true or sends false if not
So my first try at this was to use where('merchant.iso_id', '=', auth()->user()->isIso())
But that returns that the column does not exist because for some reason, it's not switching from the transaction model to the merchant one.
I am not sure how to use the stuff inside with() as a selector for my where()
Any help would be appreciated!
Try using whereHas to add the constraint:
$query = Transaction::with(['customer', 'batch'])
->whereHas('merchant', function ($q) {
$q->where('iso_id', auth()->user()->isIso());
})
->select(sprintf('%s.*', (new Transaction)->table))
->get();

How can I get the laravel join method without using foreach command?

How can I get the laravel join method without using foreach command? How can I solve it without using the Foreach command
{{$app->name}} I used to this type. But I'm constantly getting error.
Controller.php file content
public function show($id)
{
$show = Duty::where('duty_id', '=', $id)->count();
if ($show!=0){
$app = DB::table('users')
->join('duties', 'duties.appointed_user_id', '=', 'users.id')
->select('users.name', 'duties.*')
->get();
$data = Duty::where('duty_id', '=', $id)->get();
return view('duty.show', compact('data', 'app'));
}
else
{
return redirect()->back()->with('status', 'Sorun oluştu');
}
}
Property [name] does not exist on this collection instance. (View: D:\xampp\htdocs\personality\resources\views\duty\show.blade.php)
You have a list (collection) of users, not a single user. That is why you can't get just the name from it, because it doesn't know which one to get the name of. This problem has nothing to do with using the join method.
If you only expect to get one result from your query, you could change from ->get() to ->first(). This would allow you to call {{$app->name}} without breaking. But only do this if you expect a single result and use first.
If you expect more than one user, there is no way to display the names without looping in some way.
That's what relationships are for. In that case you could do User::with(:duties'). Or in your case the other way around would probably work better Duty::find($id)->with('user')

Refactor whereHas to use via global scopes in Laravel

I've 2 models, CoreChallenge and Challenge. Below are relations between table.
I want to fetch Challenges which has core_challenges active. I tried to do putting global scope in CoreChallenge model, but when I'm getting null in relationship when Corechallenge is inactive.
I've done it this way
$challenges = Challenge::with('core_challenge')->whereHas('core_challenge', function($q){
$q->where('status', '=', 'active');
})->get();
I want to do it using global scopes
Global scope on CoreChallenge gives me null, but I want that it's parent (Challenge) should not load even, like in whereHas. Is there any way?
I have stumbled to the same approach, but when the table got bigger (core_challenges_table in your scenario), whereHas ended up being very slow (around 1min response time).
So I used a solution like this:
$ids = CoreChallenge::where('status', 'active')->pluck('id');
$challenges = Challenge::with('core_challenges')
->whereIn('core_challenge_id', $ids)
->get();
With this approach, my query reduced to 600~ms from 1min.
Which can be translated to Model scopes
class Challenge {
public function scopeActive($query) {
$activeIds = CoreChallenge::where('status', 'active')->pluck('id');
return $query->whereIn('core_challenge_id', $ids);
}
}
Challenge::with('core_challenges')->active()->get();

Can I put a collection or array into the where clause on laravel eloquent?

$collection=["c","a","f","h","j","o","k"]
$total_sums=Models::select('count')->whereIn('class',['c','a','f','h','j','o','k'])
->get()
->sum('count');
can I use variable $collection like this?
$total_sums=Models::select('count')->whereIn('class',[''.$collection.''])
->get()
->sum('count');
You can use both.
whereIn() accepts both Array and a Collection.
You just simply pass it as a second parameter.
$array = ["c","a","f","h","j","o","k"];
$collection = collect($array);
$total_sums=Models::select('count')->whereIn('class', $array)
->get()
->sum('count');
// works
$total_sums=Models::select('count')->whereIn('class', $collection)
->get()
->sum('count');
// also works!
No because $collection is already an array. When you try to concatenate it to a string, I believe your query will look like the following...
select count from models where class in ('Array');
What you probably actually want to do is...
->whereIn('class', $collection)

Where clause inside whereHas being ignored in Eloquent

Im trying to make a query using whereHas with eloquent. The query is like this:
$projects = Project::whereHas('investments', function($q) {
$q->where('status','=','paid');
})
->with('investments')
->get();
Im using Laravel 5.2 using a Postgres driver.
The Project model is:
public function investments()
{
return $this->hasMany('App\Investment');
}
The investments model has:
public function project() {
return $this->belongsTo('App\Project');
}
The projects table has fields id,fields...
The investments table has the fields id,project_id,status,created_at
My issue is that the query runs and returns a collection of the projects which have at least one investment, however the where clause inside the whereHas is ignored, because the resulting collection includes investments with status values different than paid.
Does anyone has any idea of what is going on?
I believe this is what you need
$projects = Project::whereHas('investments', function($q) {
$q->where('status','=','paid');
})->with(['investments' => function($q) {
$q->where('status','=','paid');
}])->get();
whereHas wil check all projects that have paid investments, with will eagerload all those investments.
You're confusing whereHas and with.
The with method will let you load the relationship only if the query returns true.
The whereHas method will let you get only the models which have the relationship which returns true to the query.
So you need to only use with and not mix with with whereHas:
$projects = Project::with(['investments' =>
function($query){ $query->where('status','=','paid'); }])
->get();
Try like this:
$projects = Project::with('investments')->whereHas('investments', function($q) {
$q->where('status','like','paid'); //strings are compared with wildcards.
})
->get();
Change the order. Use with() before the whereHas(). I had a similar problem few weeks ago. Btw, is the only real difference between the problem and the functional example that you made.

Resources