简体   繁体   English

Laravel一对多关系查询

[英]Laravel query on one-to-many relationship

I have Post and Comment models. 我有PostComment模型。 Post and Comment have one-to-many relationship, so one post can have many comments. PostComment具有一对多关系,因此一个帖子可以有很多评论。 Every comment has a user foreign field ( User and Comment have also one-to-many). 每个评论都有一个用户外部字段(“ User和“ Comment也有一对多)。

I want to get posts where a specific user commented on. 我想获得特定用户发表评论的帖子。 We can assume that, a user could write a comment on a post only once. 我们可以假设,一个用户只能在一个帖子上发表评论一次。

You can use the Has Many Through relationship. 您可以使用“ Has Many Through关系。 The "has-many-through" relationship provides a convenient shortcut for accessing distant relations via an intermediate relation. “具有多次通过”关系为通过中间关系访问远处的关系提供了方便的快捷方式。

class User extends Model
{
    public function posts()
    {
        return $this->hasManyThrough('App\Post', 'App\Comment');
    }
}

Now you can get all posts where the user has commented by accessing this $user->posts 现在,您可以通过访问此$user->posts获得用户已评论的所有$user->posts

You can add additional relationship for Post and User models. 您可以为发布和用户模型添加其他关系。

class User extends Model {
// add this to connect your user to your post through the comment 
// (assuming one to many relationship between Comment and Post is working well)
  public function posts()
  {
     return $this->hasManyThrough(Post::class, Comment::class);
  }
}

So you can get the posts that specific user has commented on with this $user->posts()->get() 因此,您可以通过此$user->posts()->get()特定用户已评论的$user->posts()->get()

You can read more about HasManyThrough here 您可以在此处阅读有关HasManyThrough的更多信息

Assuming that the Users in your app can create Posts as well comment on posts created by other users, you could have the relations as under: 假设您应用中的用户可以创建帖子 ,也可以评论其他用户创建的帖子 ,则您的关系如下:

The User Model 用户模型

namespace App;

use App\Post;
use App\Comment;
use Illuminate\Database\Eloquent\Model;

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

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

    public function commentedPosts()
    {
        $posts = Post::whereHas('comments', function ($query){
            $query->whereUserId($this->id);
        })->get();
        return $posts;
    }
}  

The Post Model 邮政模型

namespace App;

use App\Comment;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    public function comments()
    {
        return $this->hasMany(Comment::class);
    }
}

The Comment Model 评论模型

namespace App;

use App\Post;
use App\User;
use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
    public function post()
    {
        return $this->belongsTo(Post::class);
    }

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

Then to get the Posts where the given User has commented you can use 然后获取给定用户发表评论的帖子 ,您可以使用

$user->commentedPosts();

I think this can help you: 我认为这可以帮助您:

Post::whereHas('comments', function($q) use($userId){
$q->whereHas('user', function($qq) use ($userId)
{
    $qq->where('id',$userId);
}})->get();

When we loading related models we can use function whereHas if we want to filter query by related model. 加载相关模型时,如果要按相关模型过滤查询,可以使用whereHas函数。 So here we have Post->Comment->User. 所以这里有Post-> Comment-> User。 And we want to make criteria by specific User. 我们希望根据特定用户制定标准。 So in this example i pass two times variable $userId with keyword "use" so i can use it in inner closure. 因此,在此示例中,我通过关键字“ use”传递了两次变量$ userId,以便可以在内部闭包中使用它。 I also pass first variable $q with means its an comments query, so i can filter by any comments rule. 我还通过第一个变量$ q表示其评论查询,因此我可以按任何评论规则进行过滤。 And again i use same. 再次,我使用相同的。 'comments' and 'user' has to be name of your relation function so if in your post model you have anything different from function comments to return comments with posts you should change 'comments' to your function name, also and for 'user'. 'comments'和'user'必须是您的关系函数的名称,因此,如果在您的帖子模型中,您有什么不同于函数评论的内容,以返回带有帖子的评论,则也应将'comments'更改为您的函数名,以及'user' 。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM