Laravel 4 - 如何在一个查询中为每条记录获取最新的with()

时间:2013-12-13 07:44:46

标签: php laravel laravel-4 eloquent

我正在使用laravel 4中的消息传递系统。我有以下表用户,对话,conversation_user(数据透视)和消息。用户和对话有很多关系,对话有很多消息,用户有很多消息。我得到像这样的用户的对话:¨

$usersConversations = Auth::user()->conversations;

然后我循环遍历它们以使它们的id能够仅选择那些消息用户和消息,如下所示:

if(0 < $usersConversations->count()) {
    foreach ($usersConversations as $conversation) {
        $conversationIds[] = $conversation->id;
    }
    $conversations = Conversation::with('users', 'messages')->whereIn('id', $conversationIds)->get();
} else {
    $conversations = false;
}

但这将返回每个对话的所有用户和所有消息。我不是所有用户,而是每个对话的最新消息。所以我尝试这样做:

$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);
}

这确实让我得到了最新消息,但只有最新消息,而且只有一封消息,无论有多少次。我不想为每个对话留言。

任何人都可以帮我解释如何构建该查询吗?提前谢谢。

1 个答案:

答案 0 :(得分:1)

以下是您要找的内容。

$conversations = Conversation::with(array('users', 'messages' => function($query){
    $query->orderBy('created_at', 'desc')
        ->take(1);
})->get();

无需使用latestMessage功能。

编辑:如果关系不是1-1,则返回的项目将是一个集合。即使您使用first()而不是take(1)。老实说,我认为这不是故意的,但要解决这个问题,请务必输出您的信息:

foreach($conversations as $conversation){
    echo $conversation->messages->first()->YOUR_FIELD;
}