我有一个Posts
和一个Comments
表,每个帖子可以有多个评论。
我想进行一个查询,以获取所有帖子以及所有登录用户的评论。
这是我到目前为止所拥有的:
$posts = Post::select('posts.*')
->with(['comments' => function($query) {
if (Auth::check()) {
$query->where('user_id', Auth::user()->id);
}
}])
->get();
我的Post.php
模型类如下所示:
class Post extends Model
{
public function comments()
{
return $this->hasMany('AppComment');
}
}
当用户登录时,查询将返回正确的结果。
但是当用户未登录时,它会返回所有用户的评论,而不是不返回任何内容(因为用户已登录,因此他们没有评论(。
我该如何解决这个问题?
你可以在你的帖子模型中做一个小技巧:
class Post extends Model
{
public function comments()
{
if(Auth::check()) {
return $this->hasMany('AppComment')->where('user_id', Auth::user()->id);
}else{
return $this->hasMany('AppComment')->where('user_id',-1);
}
}
}
然后简单地:
$posts = Post::select('posts.*')->with('comments')->get()
因此,如果用户未登录,它将返回所有user_id"-1"的评论,这将什么都不是
我能想到两种方法。
首先,您只能在用户登录时加载注释:
$posts = Post::select('posts.*');
if(Auth::check()) {
$posts->with(['comments' => function($query) {
$query->where('user_id', Auth::user()->id);
}]);
}
$posts = $posts->get();
或者,您可以加载所有评论,但如果用户未登录,则将user_id
设置为 null。由于每个注释都应该有一个user_id
因此不会返回任何注释。
$posts = Post::select('posts.*')
->with(['comments' => function($query) {
$query->where('user_id', Auth::check() ? Auth::id() : null);
}])
->get();
第二个中的代码看起来更干净 IMO,但第一个代码将防止执行不必要的查询。
你可以把它分开,更清晰实用:
$posts = Post::all();
在您的 Post 模型中,创建一个将返回所有用户评论的函数:
public function userComments()
{
return $this->comments->where('user_id', Auth::user()->id);
}
我想在你看来,你有一个foreach来迭代所有帖子,在你的foreach中,你加载帖子的评论,所以你可以这样做:
@foreach($posts as $post)
$post->userComments()
@endforeach