我有四张桌子。 User, Conversations, Message and Conversation_Participants
。
(我希望你在这张图片中找不到关系错误)
我尝试添加功能
public function conversations(){
return $this->belongsToMany(Conversation::class, 'conversation_participants', 'user_id', 'conversation_id');
}
到User::class
但如果我致电User::with('conversations')->get()
我只会获得所有现有用户。我究竟做错了什么?首先,我希望获得当前用户参与的所有对话,其次我希望获得所有对话接收者。
我也试过
public function participants()
{
return $this->belongsToMany(User::class, 'conversation_participants', 'user_id', 'conversation_id');
}
<{1>}中的,Conversation::class
即使是那些用户未参与的对话,也能获得所有对话。
我真的很困惑atm:/
答案 0 :(得分:2)
在User
模型中添加以下内容:
public function conversations() {
return $this->belongsToMany(Conversation::class, 'conversation_participants', 'users_id', 'conversations_id');
}
这是你的Conversation
型号:
public function participants() {
return $this->belongsToMany(User::class, 'conversation_participants', 'conversation_id', 'users_id');
}
如果您想更轻松地链接表格,read up on conventions。
要获取用户参与的所有会话,请运行以下内容(假设您已加载用户):$user->conversations()
以获取用户所在的所有会话。
如果您希望所有用户与所有与会者保持联系,请执行以下操作:$users = Users::with('conversations.participants')->get()
。您现在可以按如下方式循环:
foreach($users as $user) {
foreach($user->conversations as $conversation) {
foreach($conversations->participants as $participant) {
// do fancy stuff here
}
}
}
请注意,您启动的用户也是参与者,因此您可能需要再次过滤掉该用户。
如果你想获得更多花哨(但使用更多资源),你甚至可以查询对话中的所有消息!
User::with('conversations.participants', 'conversations.messages.user')->get()
但这只适用于在图片{@ 1}}
的上表中设置第二组关系时修改强>
在评论中,OP询问是否可以限制从数据库中检索的消息量,这可能是我所知道的,但我现在不知道这是否是最佳方式:
从第一个预先加载的部分中删除消息:
(conversations <-> messages <-> users)
之后,在循环对话时,延迟加载消息:
User::with('conversations.participants')
之后使用$ conversation-&gt;消息访问它们。
注意强>
我认为这可以一次完成,但我现在没有设置为你测试这个。
修改2
在Ronon添加了另一条评论之后,这就是我想出的:
在$conversation->load(['messages' => function($query){
$query->take(5);
}, 'users']);
模型中添加新关系:
Conversation
因此,您现在可以这样做:
public function last_messages() {
return $this->hasMany(Message::class, 'conversation_id', 'id')->latest()->limit(2);
}
如果您仍想要所有消息,可以使用User::with('conversations.participants', 'conversations.last_messages.users')->get()
关系。如果您想要更少,请使用messages
。
答案 1 :(得分:1)
调用User::with('conversations')->get()
未指定用户。我可能会误读,但我认为您正在寻找以下内容:
$user = User::with('conversations')->find(1);
$userConversations = $user->conversations;
将为您提供用户及其对话。