Laravel 4.1 нетерпеливая загрузка вложенных отношений с ограничениями

Я пытаюсь получить нетерпеливую загрузку вложенных отношений с ограничениями для работы. Кажется, все дают один и тот же пример вложенных отношений с нетерпеливой загрузкой:

$users = User::with('posts.comments')->get();

вместо этого я хочу получить всех пользователей, связанных с сообщением данного идентификатора. Но в то же время я также хочу получить комментарии, связанные с этим сообщением.

в 4.1, я для достижения последнего, я мог бы сделать:

$comments = Comment::whereHas('post', function($query) { $query->whereId(1); })->get();

есть ли способ жениться на этих двух и ограничить вложенные отношения?

3 ответов


на самом деле гораздо проще, чем думал.

учитывая эти модели:

class User extends \Eloquent {

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

    public function comments()
    {
        return $this->hasManyThrough('Comment', 'Post');
    }       

}

class Post extends \Eloquent {

    public function user()
    {
        return $this->belongsTo('User');
    }

    public function comments()
    {
        return $this->hasMany('Comment');
    }       

}

class Comment extends \Eloquent {

    public function post()
    {
        return $this->belongsTo('Post');
    }

}

затем мы можем получить пользователя, который имеет данный пост, например:

$userId = 2; $postId = 5;
$user =  User::with(['comments' => function($q) use($postId) { $q->where('post_id', $postId); }])->find($userId);

Это не будет работать при использовании get (), поскольку он не ограничивает пользователей только теми, кто связан с данным сообщением. Но это нормально, так как нас интересует только один пост post_id $postId. Поскольку сообщение принадлежит одному и только одному пользователю, нам не нужно беспокоиться о других пользователях. Поэтому мы можем используйте find() или first () для получения фактических результатов.

кроме того, "среднее" отношение, т. е. "сообщение", автоматически возвращается, и мы можем получить его, выполнив следующее без необходимости использовать дополнительное "С" , как было предложено в предыдущем ответе:

var_dump($user->posts);

Если отношения в моделях можно просто сделать:

$user = User::with('posts.comments')->get();

вы можете добавить столько отношений, сколько хотите ( или до предела памяти ;)).

Он также работает со сводными таблицами.


трудно достичь этого в контексте User - >Post - > Comment, но вы можете легко сделать это, начиная с Post, если это вам подходит:

Post::with('users')->with('comments')->find(1);

как он будет загружать всех пользователей и все комментарии, связанные с данным сообщением.

-- edit: не доверяйте первому предложению, это так просто:

// $id of the post you want

User::with(['comments' => function ($q) { // this is hasManyThrough relation
  $q->where('post_id',$id);               // comments only related to given post
}])->with(['posts' => function ($q) {
  $q->whereId($id);                       // here we load only the post you want
}])->whereHas('posts', function ($q) {
  $q->whereId(1);                         // here we filter users by the post
})->get();

имейте в виду, что Laravel будет запускать 3 запроса, чтобы сделать это