使用 laravel 关系获取对话线程,包括最后一条消息
Get thread of conversations including the last message using laravel relationship
我在尝试使用模型关系获取每个对话的最后一条消息和未读消息数时遇到问题:
|id | user_id | recipient_to | message | read | created_at | updated_at |
+---+---------+--------------+-------------------+------+------------+------------+
| 1 | 1 | 2 | Hi | 1 | | |
| 2 | 2 | 1 | How are you? | 1 | | |
| 3 | 1 | 3 | Hi | 0 | | |
| 4 | 1 | 2 | Could you help me?| 0 | | |
我构建了检索特定用户对话线程的查询,包括与收件人的关系:
型号:App\Models\Message.php
public function userTo()
{
return $this->belongsTo('App\Models\User', 'recipient_to', 'id');
}
控制器
$conversations = Message::where('user_id', 1)
->with([
'userTo' => function ($query) {
$query->select('id', 'name', 'last_name', 'avatar');
}
])
->distinct()
->get(['recipient_to']);
回复:
[
{
"recipient_to": 2,
"user_to": {
"id": 2,
"name": "Jessyca",
"last_name": "Skiles",
"avatar": "https://i.pravatar.cc/150?u=hayes.rachael@example.org"
}
},
{
"recipient_to": 3,
"user_to": {
"id": 3,
"name": "Rocio",
"last_name": "Rosenbaum",
"avatar": "https://i.pravatar.cc/150?u=yspencer@example.org"
}
}
]
如何建立 return 最后一条消息与未读消息数之间的关系?
这篇post我已经看过了,觉得很有意思,虽然目的是研究Laravel的关系
Get latest message (row) per user in Laravel
21/08/2019 --- Progress
如果我在用户模型中创建了两个关系,我得到了对话中每个用户发送的最后一条消息,有没有办法创建一个额外的关系并合并到 return 最近的?
public function latestMessageTo()
{
return $this->hasOne('App\Models\Message', 'recipient_to')->orderBy('created_at', 'desc')->latest();
}
public function latestMessageFrom()
{
return $this->hasOne('App\Models\Message', 'user_id')->orderBy('created_at', 'desc')->latest();
}
我找到了一个解决方案,不要使用eloquent,但是它满足需要。
也许我们可以找到使用 eloquent 的解决方案,尽管我读到过使用本机 SQL 查询而不是 eloquent 更有效。
DB::select('
SELECT t1.*
FROM messages AS t1
INNER JOIN
(
SELECT
LEAST(user_id, recipient_to) AS user_id,
GREATEST(user_id, recipient_to) AS recipient_to,
MAX(id) AS max_id
FROM messages
GROUP BY
LEAST(user_id, recipient_to),
GREATEST(user_id, recipient_to)
) AS t2
ON LEAST(t1.user_id, t1.recipient_to) = t2.user_id AND
GREATEST(t1.user_id, t1.recipient_to) = t2.recipient_to AND
t1.id = t2.max_id
WHERE t1.user_id = ? OR t1.recipient_to = ?
',[auth()->guard('api')->user()->id, auth()->guard('api')->user()->id]);
有什么意见吗?
我在尝试使用模型关系获取每个对话的最后一条消息和未读消息数时遇到问题:
|id | user_id | recipient_to | message | read | created_at | updated_at |
+---+---------+--------------+-------------------+------+------------+------------+
| 1 | 1 | 2 | Hi | 1 | | |
| 2 | 2 | 1 | How are you? | 1 | | |
| 3 | 1 | 3 | Hi | 0 | | |
| 4 | 1 | 2 | Could you help me?| 0 | | |
我构建了检索特定用户对话线程的查询,包括与收件人的关系:
型号:App\Models\Message.php
public function userTo()
{
return $this->belongsTo('App\Models\User', 'recipient_to', 'id');
}
控制器
$conversations = Message::where('user_id', 1)
->with([
'userTo' => function ($query) {
$query->select('id', 'name', 'last_name', 'avatar');
}
])
->distinct()
->get(['recipient_to']);
回复:
[
{
"recipient_to": 2,
"user_to": {
"id": 2,
"name": "Jessyca",
"last_name": "Skiles",
"avatar": "https://i.pravatar.cc/150?u=hayes.rachael@example.org"
}
},
{
"recipient_to": 3,
"user_to": {
"id": 3,
"name": "Rocio",
"last_name": "Rosenbaum",
"avatar": "https://i.pravatar.cc/150?u=yspencer@example.org"
}
}
]
如何建立 return 最后一条消息与未读消息数之间的关系?
这篇post我已经看过了,觉得很有意思,虽然目的是研究Laravel的关系 Get latest message (row) per user in Laravel
21/08/2019 --- Progress
如果我在用户模型中创建了两个关系,我得到了对话中每个用户发送的最后一条消息,有没有办法创建一个额外的关系并合并到 return 最近的?
public function latestMessageTo()
{
return $this->hasOne('App\Models\Message', 'recipient_to')->orderBy('created_at', 'desc')->latest();
}
public function latestMessageFrom()
{
return $this->hasOne('App\Models\Message', 'user_id')->orderBy('created_at', 'desc')->latest();
}
我找到了一个解决方案,不要使用eloquent,但是它满足需要。
也许我们可以找到使用 eloquent 的解决方案,尽管我读到过使用本机 SQL 查询而不是 eloquent 更有效。
DB::select('
SELECT t1.*
FROM messages AS t1
INNER JOIN
(
SELECT
LEAST(user_id, recipient_to) AS user_id,
GREATEST(user_id, recipient_to) AS recipient_to,
MAX(id) AS max_id
FROM messages
GROUP BY
LEAST(user_id, recipient_to),
GREATEST(user_id, recipient_to)
) AS t2
ON LEAST(t1.user_id, t1.recipient_to) = t2.user_id AND
GREATEST(t1.user_id, t1.recipient_to) = t2.recipient_to AND
t1.id = t2.max_id
WHERE t1.user_id = ? OR t1.recipient_to = ?
',[auth()->guard('api')->user()->id, auth()->guard('api')->user()->id]);
有什么意见吗?