TL;DR: Need latest message from each sender.
In my Laravel application I have two tables:
Users:
Messages:
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
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;
this may be a solution (not tested though)
User::with([
'messages' => function ($q) {
$q->select('sender_id', 'body')->groupBy('sender_id')->orderBy('created_at', 'desc');
}
])->find(1);
I like a simpler approach which is mentioned here.
In your User
model additionally to existing messages()
relationship, add this relationship
public function latestMessage()
{
return $this->hasOne(Message::class, 'recipient_id')->latest();
}
Then when you query simply query like this.
$messages = User::with('latestMessage')->get();
$messages
contains latest message per user.
Edit
In order to order the result by datetime/id you could do it like this.
$messages = User::with(['latestMessage' => function($message) {
$message->orderBy('id', 'desc');
}])->get();
$messages
contains latest message per user ordered by id
. Refer this answer
Maybe you can try this one:
$user = \Auth::user();
// Get the latest date
$last_date_created = Message::latest()->first()->created_at; // also check for possible null
// Get the date only - use to specify date range in the where section in the eloquent query
$target_date = date('Y-m-d', strtotime( $last_date_created ) );
// Retrieve the messages
$latest_posts = Message::where('recipient_id', $user->id)
->where('created_at', '>=', $target_date . ' 00:00:00')
->where('created_at', '<=', $target_date . ' 23:59:59')
->groupBy('sender_id')
->groupBy('created_at')
->get();
return $latest_posts;
This may not be very efficient since it took two queries to do the job but you will gain benefits thru code readability.
I hope it works the way it should be. I haven't tested it though but that's how I usually do this... Cheers!
You can try this one
Messages::where('recipient_id',**{USER_ID}**)
->group_by('sender_id')
->order_by('id','desc')
->get();