Get latest message (row) per user in Laravel

后端 未结 9 2497
感动是毒
感动是毒 2021-02-19 01:04

TL;DR: Need latest message from each sender.

In my Laravel application I have two tables:

Users:

  • id
  • name

Messages:

相关标签:
9条回答
  • 2021-02-19 02:06

    Why not simply accessing the messages, like this -

    // get the authenticated user
    $user = \Auth::user(); 
    
    // find the messages for that user
    return User::with('message')->find($user->id)->messages;
    
    0 讨论(0)
  • 2021-02-19 02:07

    This is the most "Eloquent way" I have found of doing this:

    In User model:

    public function messages() {
        return $this->hasMany(Message::class, 'recipient_id');
    }
    
    public function latestMessagePerSender()
    {
        return $this->messages()
            ->whereNotExists(function ($query) {
                $query->from('messages AS m2')
                    ->whereRaw('m2.sender_id = messages.sender_id')
                    ->whereRaw('m2.created_at > messages.created_at');
        });
    }
    

    Then just $user->latestMessagePerSender

    0 讨论(0)
  • 2021-02-19 02:07

    I found this solution in another forum, I think that is what you were looking for. I post it so it can be useful for other users

            DB::select('
                SELECT t1.*
                FROM messages AS t1
                INNER JOIN
                (
                    SELECT
                        LEAST(sender_id, recipient_id) AS user_id,
                        GREATEST(sender_id, recipient_id) AS recipient_id,
                        MAX(id) AS max_id
                    FROM messages
                    GROUP BY
                        LEAST(sender_id, recipient_id),
                        GREATEST(sender_id, recipient_id)
                ) AS t2
                    ON LEAST(t1.sender_id, t1.recipient_id) = t2.sender_id AND
                       GREATEST(t1.sender_id, t1.recipient_id) = t2.recipient_id AND
                       t1.id = t2.max_id
                    WHERE t1.sender_id = ? OR t1.recipient_id = ?
                ', [auth()->guard('api')->user()->id, auth()->guard('api')->user()->id]);
    

    original post: https://laracasts.com/discuss/channels/laravel/get-the-latest-message-of-chat-model-with-mysql-just-cannot-get-the-idea-how-to-do-this?page=1#reply=392529

    0 讨论(0)
提交回复
热议问题