Laravel中使用musonza/chat包如何隐藏无消息的会话?
Got it, let's tackle this problem with the musonza/chat package in Laravel. The core idea is to filter out any conversation that has no associated messages—either at the query level (most efficient) or in your view. Here's how to do both:
1. Filter Conversations at the Query Level (Recommended)
This approach cuts down on unnecessary data fetching by only pulling conversations with at least one message directly from the database.
The Conversation model in the musonza/chat package has a one-to-many relationship with the Message model, so we can use Laravel's whereHas() clause to filter out empty conversations:
use Musonza\Chat\Facades\Chat; use Illuminate\Support\Facades\Auth; // In your controller's inbox method public function inbox() { // Fetch only conversations with messages for the authenticated user $conversations = Chat::conversations() ->forUser(Auth::user()) ->whereHas('messages') // This filters out empty conversations ->orderBy('updated_at', 'desc') // Keep your existing ordering logic if needed ->get(); return view('inbox', compact('conversations')); }
If you prefer using Eloquent relationships directly instead of the facade, you can also write it like this:
$conversations = Auth::user()->conversations() ->whereHas('messages') ->orderBy('updated_at', 'desc') ->get();
Bonus: Add a Reusable Scope
To make this filter reusable across your app, extend the package's Conversation model with a custom one and add a scope:
// app/Models/Chat/Conversation.php namespace App\Models\Chat; use Musonza\Chat\Models\Conversation as BaseConversation; class Conversation extends BaseConversation { public function scopeWithMessages($query) { return $query->whereHas('messages'); } }
Update the package's config to use your custom model (if you haven't already), then use the scope like this:
$conversations = Chat::conversations() ->forUser(Auth::user()) ->withMessages() ->get();
2. Filter in the View (Quick Fix, Less Efficient)
If you need a fast workaround without modifying your controller query, you can check for messages directly in your Blade view:
{{-- In your inbox.blade.php --}} @foreach($conversations as $conversation) @if($conversation->messages->isNotEmpty()) <!-- Your conversation display code here --> <div class="conversation-item"> {{ $conversation->name }} <!-- Other conversation details --> </div> @endif @endforeach
Note: This method fetches all conversations first, then filters them in the view—this is less efficient than the query-level filter, especially if you have a lot of conversations.
Why This Works
When you empty a conversation, you're deleting all its associated messages. The whereHas('messages') clause checks that there's at least one related message record, so any conversation with zero messages gets excluded from your inbox results.
内容的提问来源于stack exchange,提问作者Jadasdas

