简体   繁体   中英

Laravel 4 - How to get the latest in with() for each record in one query

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM