Laravel 7 Query with() and using Where() - laravel

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();

Related

How to filter a Laravel collection

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.

Eloquent, Retrieve results from nested relations query

Here is my query:
$profile = \App\ShippingProfile::findOrFail(2)
::with('costs')
->with( ['methods.zone' => function($query) {
$query->where('id', 2);
}])->get();
So I need shipping profile id 2, with related "costs" model and its related "method" with id 2, and the method's related "zone".
But I don't know how to get the result. If I try ->get() , I get all ShippingProfiles, and if try
->first() I get profile id 1.
So how would I retrieve the results? I have only seen "get", "first" and "find"...or is there something wrong with the query?
There are a few problems with your current code. First of all you have a syntax error:
$profile = \App\ShippingProfile::findOrFail(2)
::with('costs')
The second :: should be ->.
Secondly, when you do firstOrFail() you're actually executing the query and returning a Model as a result. So when you're then chaining the rest onto the Model instance you're likely ending up with an error.
There are a couple of ways you can achieve your goal however. First of all, try using whereKey which adds a where clause to your query against the primary key, (just like using findOrFail does - but it doesn't immediately execute the query and return the model) and use first() to grab the model instance with the relations eager loaded:
$profile = \App\ShippingProfile::whereKey(2)
->with(['costs', 'method.zone' => function ($query) {
$query->where('id', 2);
}])
->first();
Alternatively, if you already have an instance of your model, you can use load(...), in the same way as you would use with(...) to load your relations:
$profile = App\ShippingProfile::findOrFail(2);
$profile->load(['costs', 'method.zone' => function ($query) {
$query->where('id', 2);
}]);

Laravel Eloquent get result where relation data is null

I have two Models User and Owner with many to many relationship
I want to fetch only those users who don't have owner
how can I get using eloquent
i tried
$query = User::whereHas('userOwners', function ( $subquery ){
$subquery->whereNull('owner_id');
})->get();
but not working.
Eloquent has a way to query an absent relationships, it should work like this in your case:
$query = User::doesntHave('userOwners')->get();
User::with('userOwners')
->whereHas('userOwners', function ($query) {
$query->wherehas('owner_id');
})
->where('user_status', 1)->get();
use second where if you want to filter on user
use first where if you want to filter on Owner
I think you should just change your query like:
$query = User::whereHas('userOwners')->get();
Hope this work for you!!!

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.

Laravel Eloquent: Get current id from inner function

I know, we can do this in the controller:
User::with('post')->get();
It will get every user's post from the database, based on users.id.
But the problem is, I want to do this:
User::with(['post' => function($query) {
# Throw users.id here...
}])->get();
How to do that?
You should get the users first, and then load related posts with a separate query and merge them manually.
$users = User::get();
$posts = Post::whereIn('user_id', $users->pluck('id'))->get(); // Get your additional data in this query
$users->each(function ($user) use ($posts)
{
$user->posts = $posts->where('user_id', $user->id);
});
Note: I did not test the code above. It's just an example to show you how to accomplish what you are trying to do.

Resources