I'm working on a messaging system in laravel 4. I have the following tables users, conversations, conversation_user(pivot) and messages. users and converations have many to many relationship, conversations have many messages and users have many messages. I get the conversations of a user like so:¨
$usersConversations = Auth::user()->conversations;
Then I loop over them to get their ids to be able to select only those messages users and messages like so:
if(0 < $usersConversations->count()) {
foreach ($usersConversations as $conversation) {
$conversationIds[] = $conversation->id;
}
$conversations = Conversation::with('users', 'messages')->whereIn('id', $conversationIds)->get();
} else {
$conversations = false;
}
but this returns all users and all messages for each of the conversations. I wan't all the users but only the latest message for each conversation. So I tried doing this instead:
$conversations = Conversation::with('users', 'latestMessage')->whereIn('id', $conversationIds)->get();
// and have this in my Conversation model
public function latestMessage() {
return $this->hasMany('Message')->orderBy('created_at', 'desc')->take(1);
}
This does get me the latest message, but only the very latest, and only one, no matter how many convesations there are. I wan't one message for each of the conversations.
Can anyone help me with how to construct that query? Thanks in advance.
Here is what you are looking for.
$conversations = Conversation::with(array('users', 'messages' => function($query){
$query->orderBy('created_at', 'desc')
->take(1);
})->get();
There is no need to use the latestMessage
function.
EDIT : The item returned will be a collection if the relationship is not a 1-1. Even if you use first()
instead of take(1)
. Honestly I think it's not intended, but to work around this, make sure to output your messages as such:
foreach($conversations as $conversation){
echo $conversation->messages->first()->YOUR_FIELD;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.