Как переписать запрос на Eloquent?
У меня есть следующий запрос, который выводит мне нужный результат (список чатов пользователя и последнее сообщение в чате):
DB::table('chat_room_user')
->join('chat_rooms', 'chat_room_user.chat_room_id', 'chat_rooms.id')
->join('users', 'chat_room_user.user_id', 'users.id')
->join('messages', 'messages.chat_room_id', 'chat_rooms.id')
->select('chat_rooms.id', 'chat_rooms.title','messages.message AS last_message','messages.updated_at')
->where('users.id', $id)
->whereIn('messages.id', function ($query) {
$query->select(DB::raw('MAX(messages.id)'))->from('messages')->groupBy('messages.chat_room_id');
})
->orderBy('messages.created_at', 'desc')
->get();
Я получаю такой результат:
{
"result": [
{
"id": 5,
"title": "Chat 3",
"last_message": "Hello",
"updated_at": null
},
{
"id": 1,
"title": "test chat",
"last_message": "Голосовое сообщение",
"updated_at": "2022-07-27 15:50:03"
}
]
}
Хотелось бы переписать запрос с использованием возможностей Eloquent, но у меня не получается. Создал модель: ChatRoom, User, Messages. Модели связал
User.php
public function chatRooms(): BelongsToMany
{
return $this->belongsToMany(ChatRoom::class, 'chat_room_user')
->withTimestamps();
}
Message.php
public function chatRoom(): BelongsTo
{
return $this->belongsTo(ChatRoom::class);
}
public function scopeLastInChat(Builder $query): Builder
{
return $query->select('message AS last_message', 'updated_at')->whereIn('id', function
($query) {
$query->select(DB::raw('MAX(messages.id)'))->from('messages')->groupBy('messages.chat_room_id');
})->orderBy('created_at', 'DESC');
}
ChatRoom.php
public function messages(): HasMany
{
return $this->hasMany(Message::class);
}
public function users(): BelongsToMany
{
return $this->belongsToMany(User::class, 'chat_room_user');
}
Теперь в своем контроллере я получаю вроде все, что мне нужно:
public function chatRoomsByUser(int $id): JsonResponse
{
$user = User::query()->find($id);
$chatRooms = $user->chatRooms;
$messages = Message::lastInChat()->get();
return response()->json(['result' => $chatRooms->merge($messages)]);
}
Но я теперь получаю такой результат
{
"result": [
{
"id": 1,
"title": "test chat",
"created_at": "2022-07-27T11:42:36.000000Z",
"updated_at": "2022-07-27T11:42:36.000000Z",
"pivot": {
"user_id": 8,
"chat_room_id": 1,
"created_at": null,
"updated_at": null
}
},
{
"id": 5,
"title": "Chat 3",
"created_at": "2022-08-01T08:54:04.000000Z",
"updated_at": null,
"pivot": {
"user_id": 8,
"chat_room_id": 5,
"created_at": null,
"updated_at": null
}
}
],
"last_message": [
{
"last_message": "Hello",
"updated_at": null
},
{
"last_message": "Голосовое сообщение",
"updated_at": "2022-07-27T12:50:03.000000Z"
}
]
}
Как мне добится такого же рузльтат как в первом случае (с Db query) только при помощи Eloqent