Paul Wright
Paul Wright

Reputation: 455

Eloquent Eager loading

The guide for Eloquent http://laravel.com/docs/4.2/eloquent contains the following:-

Eager Load Constraints

Sometimes you may wish to eager load a relationship, but also specify a condition for the eager load. Here's an example:

$users = User::with(array('posts' => function($query)
{
    $query->where('title', 'like', '%first%');

}))->get();

In this example, we're eager loading the user's posts, but only if the post's title column contains the word "first".

How do you turn this around, so that you only get Users that have a post where the title column contains the word "first"?

In other words, I want ONLY the Users that have a posts containing the word "first" and I want to eager load those posts. If there are 10 Users and 3 of those Users have a post containing the word "first", then my get() will return just 3 users, each with their eager loaded posts that have a title containing "first".

Upvotes: 2

Views: 373

Answers (2)

Paul Wright
Paul Wright

Reputation: 455

Just to show the final syntax for Ciccio answer above.

users = User::whereHas('posts', function($q) use ($first)
{
   $q->where('title', 'like', "%{$first}%");
})->with(array('posts' => function($q) use ($first) {
   $q->where('title', 'like', "%{$first}%");
}
))->get();

Just as a note, when I first ran this, I was timing out at 30 seconds. My "Posts" table had 30,000 rows, not massive, but enough to slow everything down. Adding an extra Index to the "Posts" table cut the time down to 0.2 seconds.

Upvotes: 1

Francesco de Guytenaere
Francesco de Guytenaere

Reputation: 4833

I believe you are looking for something like this (untested):

$first = 'first';
$users = User::whereHas('posts' => function($q) use ($first)
{
    $q->where('title', 'like', "%{$first}%");

})->with(['posts' => function($q) use ($first)
{
   $q->where('title', 'like', "%{$first}%");

}])->get();

Upvotes: 1

Related Questions