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 запроса, чтобы сделать это