我正在Laravel中构建一个基本的私人消息系统,并希望在两个用户(对于已登录的用户)之间显示一个消息线程列表作为基本收件箱。
目前我将所有消息存储在1个表中。该表包含“sender_id”和“recipient_id”以及消息内容。
要检索要在收件箱中显示的消息列表,我目前正在控制器中执行此操作:
//Authenticate the user
$user = auth()->user()->id;
$messagesSent = Message::where('sender_id', $user)->get();
$messagesReceived = Message::where('recipient_id', $user)->get();
$messageThreads = $messagesReceived->merge($messagesSent);
在刀片中,显示我正在执行的线程列表:
<ul class="list-group">
@foreach ($messageThreads as $message)
@if($message->user->id != $user)
<li class="list-group-item"><a href="/messages/view/{{$message->user->id}}">{{$message->user->displayName}}</a></li>
@else
<li class="list-group-item"><a href="/messages/view/{{$message->recipient->id}}">{{$message->recipient->displayName}}</a></li>
@endif
@endforeach
</ul>
正如预期的那样,这只是显示用户已发送消息或接收消息的用户的名称以及指向该线程的链接,但如果用户之间有多条消息,则其名称显然会显示多个次。
当前输出的示例
如何输出:
我希望能够确保名称&amp;链接到该线程只列出一次。
我尝试过使用distinct()和unique()但是因为sender_id&amp; recipient_id是单独的列,我仍然会得到重复的结果。
我怎样才能克服这一点。
由于
答案 0 :(得分:0)
也许是这样的:
$user = auth()->user()->id;
$messageThreads = Message::where('sender_id', $user)->orWhere('recipient_id', $user)->get();
基本上,您在一个表上执行两个类似的查询,然后通过PHP代码合并结果。上面的解决方案(未经测试)将两个查询合并为一个,因此合并发生在数据库端。
或者,您仍然可以在PHP中执行此操作(此处我假设您的消息记录的主键名为&#34; id&#34;):
$messageThreads = $messageThreads->unique('id');
但这可能会破坏消息顺序。
答案 1 :(得分:0)
$recipientIds = Message::select('recipient_id')->where('sender_id', $user)->get()->pluck('recipient_id');
$senderIds = Message::select('sender_id')->where('recipient_id', $user)->get()->pluck('sender_id');
$userIds = array_unique(array_merge($recipientIds , $senderIds ));
$users = User::whereIn('id', $userIds)->keyBy('id');
// view
@foreach($users as $user)
<li class="list-group-item"><a href="/messages/view/{{$user->id}}">{{$user->displayName}}
@endforeach
信用:https://laracasts.com/discuss/channels/laravel/list-only-unique-ids-from-2-columns