whereHas 回调中的关系过滤器与 Eloquent

Posted

技术标签:

【中文标题】whereHas 回调中的关系过滤器与 Eloquent【英文标题】:Relationship filter in whereHas callback with Eloquent 【发布时间】:2019-08-12 03:16:00 【问题描述】:

给定以下模型

对话:id、user_id、

消息:id、conversation_id、author_id、created_at

我想查询在$start$end之间有消息的所有对话,所以我这样做了:

$filterMessages = function($query) use ($start, $end) 
    $query->whereBetween("created_at", [$start, $end]);
;

$convs = Conversation::whereHas("messages", $filterMessages)
->with(["messages"  => $filterMessages]);

而且它有效。现在我需要添加一个条件:message.user_id 必须与他的对话的 user_id 匹配(在 whereHas 和 with 中)。所以我把我的回调改成这样:

$filterMessages = function($query) use ($start, $end) 
    $query->whereBetween("created_at", [$start, $end]);
    $query->where("conversations.user_id", "author_id");
;

但它不起作用。我怎么能这样做?

谢谢

【问题讨论】:

【参考方案1】:

试试这个

Conversation Model定义关系

public function userMessages()

   return $this->hasMany(Message::class, 'author_id', 'user_id'); //your relationship based on data structure


$convs = Conversation::whereHas('userMessages',function($query) use ($start, $end) 
                           $query->whereBetween("created_at", [$start, $end]);
                       )
                      ->with("userMessages")
                      ->get();

【讨论】:

我认为您误解了我的问题,因为我说过我需要“message.user_id 必须与他的对话的 user_id 匹配”。日期查询已经有效。谢谢 然后你可以定义一个与Conversation的关系查看我的最新帖子 这是个好主意,但是 userMessages 关系忽略了 conversation_id 字段,因此它还返回其他会话消息:( message.user_id==conversation.user_idmessage.author_id==conversation.user_id 你能指定吗?所以我可以更新我的帖子 它是author_id

以上是关于whereHas 回调中的关系过滤器与 Eloquent的主要内容,如果未能解决你的问题,请参考以下文章

WhereHas Laravel 中的关系计数条件是啥

为啥 $ids 在 whereHas() 的回调中不可见?

Laravel - 搜索关系,包括 whereHas 中的 null

Laravel whereHas 检查嵌套关系中的最后一条最新记录

使用 whereHas 和关系列的总和进行查询

Sequelize 中的 WhereHas 方法