Skip to content
Advertisement

Can i use where condtiton after calling relation with @with method?

This code:

$users = Users::with(['posts' => function($post) use ($request) {
    $post->where('votes', '>', 100);
}])->get();

dd($users->toArray());

Return output like this:

0 => [
    "user_id" => 1
    "posts" => []
]

What can I do to return an empty array of users? I tried to do like this:

$users = Users::with(['posts'])
    ->where('posts.votes', '>', 100)->get();

dd($users->toArray());

But got an error:

Undefined table: 7 ERROR: issing FROM-clause entry for table "posts"

Advertisement

Answer

With the syntax you tried, the answer is “No”, as ->with() doesn’t perform any kind of join logic; so posts tables is not available there.

If you want to filter the User records returned based on a condition of a relationship, you need to use one of has() or whereHas() method. In your case, since you’re looking for votes > 100, with votes being a column, you need to use whereHas():

$users = Users::whereHas(['posts' => function($query) {
    return $query->where('votes', '>', 100);
}])->get();

This will limit the User record being returned to those that have 100 votes or more.

Additionally, you can use both whereHas() and with() with the same function to Filter and Eager Load the relationship (preventing extra queries from being run later). Syntax for that would be:

$closure = function ($query) {
  return $query->where('votes', '>', 100);
});

$users = Users::whereHas(['posts' => $closure]
->with(['posts' => $closure])
->get();

Complete documentation is available here:

https://laravel.com/docs/9.x/eloquent-relationships#querying-relationship-existence

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement