Zsw
Zsw

Reputation: 4107

Querying a Collection of One-to-Many Relationship

Suppose I have a User model and a Post model.

class Post extends Eloquent 
{

}

There are many users, and each User has many Post. All Post belongs to a User.

class User extends Eloquent 
{
    public function posts()
    {
        return $this->hasMany('Post');
    }
}

I know that I can get a single User with find().

$user = User::find(1);

I know that from a single User, I can get all their posts().

$posts = User::find(1)->posts;

However, suppose now I have multiple users.

$users = User::all();

I wish to access all the posts that this collection of users have. Something along the lines of

$posts = User::all()->posts;

This, of course, doesn't work. However, in theory, it should be functionally equivalent to

$posts = Post::all()

Is there a way to do something similar to the above in Laravel 4.2?


I do not want to use Post::all(). Reason being that it would not be what I want in a more complicated example that involves constraints on User.

$postsByMaleUsers = User::where('gender', '=', 'male')->posts;

Should get all the posts made by male users.


I am also aware that I could simply use a foreach loop.

foreach($users->posts as $post)
{
    // Process result here.
}

However, suppose I am trying to return the results instead of processing the results. For example, I could have a public static function postsByMaleUsers() in the User model, and calling User::postsByMaleUsers() should return a collection of posts by male users only. In which case, the foreach loop would not suit me.

Upvotes: 2

Views: 31

Answers (1)

Joseph Silber
Joseph Silber

Reputation: 220136

Eager load the posts, then use pluck and collapse to get a flat collection of posts:

$users = User::with('posts')->where('gender', 'male')->get();

$posts = $users->pluck('posts')->collapse();

Upvotes: 1

Related Questions