【问题标题】:Laravel Eloquent - orWhereHas method - When to use it and howLaravel Eloquent - orWhereHas 方法 - 何时使用以及如何使用
【发布时间】:2021-03-17 21:03:57
【问题描述】:

我正在尝试了解一些高级的 eloquent 命令,在 Laravel 官方文档中,没有太多关于 Eloquent orWhereHas 方法的内容,也没有关于它如何工作的示例。
https://laravel.com/docs/8.x/eloquent-relationships#querying-relationship-existence

有人可以通过一个简单的例子来帮助我理解它吗?

【问题讨论】:

标签: laravel eloquent


【解决方案1】:

如何使用它:就像任何其他Eloquent 方法一样链接

User::whereHas(...)->orWhereHas(...)->get();

何时使用它:假设您有UsersPostsComments,每个用户都可以写帖子和cmets。然后你需要获得活跃用户。例如,您假设 active 为用户,该用户在过去 7 天内发表过帖子或 cmets。所以,你可以这样得到它:

$users = App\Models\User::query()
    ->whereHas('posts', function (Builder $query) {
        $query->where('created_at', '>=', Carbon::now()->subDays(7));
    })
    ->orWhereHas('comments', function (Builder $query) {
        $query->where('created_at', '>=', Carbon::now()->subDays(7));
    })
    ->get();

【讨论】:

  • 谢谢,我明白了。您的代码中只有一个不完美之处。您错过了 >= 以获取上周的值。 $query->where('created_at', '>=', Carbon\Carbon::now()->subDays(7));
  • 如果你解决了这个问题,我可以接受你的正确答案
【解决方案2】:

假设有一个博客类型的应用程序。应用程序的主要实体/模型将是 Post(博客帖子)。

当任何作者撰写和发布帖子时,

  • 博客网站的访问者可以对帖子发表评论
  • 访客可以点赞帖子

所以我们这里有 3 个模型

  • 帖子 - 可以有很多 评论
  • 帖子 - 可以有很多 喜欢

现在假设出于某种原因我们想从数据库中获取当月有 10 个或更多 cmets 或当月有 3 个或更多赞的所有 Post 记录

我们可以写一个查询

$posts = Post::whereHas('comments', function($query) {
        $query->where('created_at', '>', now()->startOfMonth();
    }, '>=', 10)
    ->orWhereHas('likes', function($query){
        $query->where('created_at', '> ', now()->startOfMonth();
    }, '>=', 3)
    ->get();

Laravel 文档:https://laravel.com/docs/8.x/eloquent-relationships#querying-relationship-existence

就像where 一样,whereHasorWhereHas 都接受闭包作为第二个参数,以实现更细粒度的查询控制。

其实whereHas应该是在你想要有更多的权力约束的时候使用的。

如果您只想检查关系记录的存在,您可以使用has 例如:

获取所有有评论或点赞的帖子记录,每页分页20个

$postsWithCommentsOrLikes = Post::has('comments')
    ->orHas('likes')
    ->paginate(20);

【讨论】:

  • 据我了解,您的代码示例可以从whereHas 更改为has,因为您没有使用回调来过滤子查询
  • 是的,我只是添加了它,但被其他东西分心了
  • 在这种情况下,如果您指定任何条件,我认为您可以使用 has 和 orHas
  • 是的@DavideCasiraghi,如果要求只是检查模型是否有相关记录,那么简单的has()orHas() 就足够了。但是,如果需要更细粒度的控制来创建对关系检查的复杂约束,那么whereHasorWhereHas 就会发挥作用,因为它们都接受闭包作为可以定义复杂查询逻辑的第二个参数。两种情况都有更新答案
猜你喜欢
  • 2021-03-18
  • 1970-01-01
  • 2020-08-13
  • 2017-02-19
  • 2014-06-04
  • 2011-06-07
  • 2017-07-06
  • 2016-02-11
  • 2017-03-04
相关资源
最近更新 更多