Laravel实时聊天系统:如何通过Eloquent获取与指定用户的最新消息
解决Laravel中获取与指定用户最新聊天消息的问题
嘿,这个需求其实不用分开查询再手动对比时间,咱们可以直接用Eloquent构建一个合并查询,一次性拿到两者之间的最新消息,下面给你几种实用的实现方式:
方法一:使用闭包组合查询条件
这是最直观的写法,把两种对话场景(你发给对方、对方发给你)用闭包包裹,然后整体按创建时间倒序取第一条:
$latestMessage = Message::where(function ($query) use ($user) { // 当前用户发送给目标用户的消息 $query->where('sender_id', auth()->user()->id) ->where('receiver_id', $user->id); })->orWhere(function ($query) use ($user) { // 目标用户发送给当前用户的消息 $query->where('sender_id', $user->id) ->where('receiver_id', auth()->user()->id); })->latest('created_at')->first();
这个查询会先筛选出你和目标用户之间的所有对话消息,然后直接取最新的那一条,省去了手动对比created_at的步骤。
方法二:使用whereRaw简化条件
如果你熟悉原生SQL,也可以用whereRaw来写更紧凑的条件:
$latestMessage = Message::whereRaw( '(sender_id = ? AND receiver_id = ?) OR (sender_id = ? AND receiver_id = ?)', [auth()->user()->id, $user->id, $user->id, auth()->user()->id] )->latest('created_at')->first();
效果和方法一完全一致,只是写法更精简,适合喜欢简洁代码的场景。
进阶:封装为模型Scope(推荐)
如果这个查询在项目中会多次用到,建议把它封装成Message模型的Scope,提升代码复用性:
在app/Models/Message.php中添加一个Scope方法:
public function scopeBetweenUsers($query, User $user1, User $user2) { return $query->where(function ($q) use ($user1, $user2) { $q->where('sender_id', $user1->id) ->where('receiver_id', $user2->id); })->orWhere(function ($q) use ($user1, $user2) { $q->where('sender_id', $user2->id) ->where('receiver_id', $user1->id); }); }
之后调用的时候就非常简洁了:
$latestMessage = Message::betweenUsers(auth()->user(), $user)->latest()->first();
这样不管在哪个地方需要获取两个用户之间的聊天记录,都可以直接用这个Scope,代码更优雅也更容易维护。
内容的提问来源于stack exchange,提问作者Faizan Ahmad
相关产品推荐
相关产品推荐

