うちでLaravelで質問回答アプリを実装しています。
対話者のメッセージボックスを作りたい、要件をまとめました:
ログイン中のユーザーはuser_meとし、他のユーザーごとに一番新しいメッセージを提示するメッセージリストを作りたいです。
そこでクリックしたら、そのユーザーとのメッセージモダルに飛ぶ。
ユーザー名は相手の名前、メッセージは対話中の一番新しいメッセージ(自分からメッセージのも含む)
SQLよりLaravelのコレクションはもっと使いやすいと思い、以下で案を。
まずuser_meと関わる全てのメッセージを時間順に並べて取得、
次に対話両方をグループとし、一番新しいメッセージだけ、リストにプッシュする。
リストに登録済のグループのメッセージはプッシュしません。
以下はMessageRepositoriesのメソッドの一部です。
namespace App\Repositories;
public function selectMessageByEachUser()
{
$me_id = user('api')->id;
$messages = Message::with(['fromUser', 'toUser'])
->where('to_user_id', $me_id)
->orwhere('from_user_id', $me_id)
->orderBy('created_at', 'desc')
->get();
$chat_room_groups = [];
$new_messages = collect();
foreach ($messages as $message) {
$match_ids_1 = [$message->from_user_id, $message->to_user_id];
$match_ids_2 = [$message->to_user_id, $message->from_user_id];
if ($new_messages->isEmpty()) {
$new_messages->push($message);
array_push($chat_room_groups, $match_ids_1);
} else {
$res = !in_array($match_ids_1, $chat_room_groups, true)
&& !in_array($match_ids_2, $chat_room_groups, true);
if ($res) {
$new_messages->push($message);
array_push($chat_room_groups, $match_ids_1);
}
}
}
return $new_messages;
}
次にメッセージコントローラは処理したリストをもらい、APIリソースをフロントエンドに発信
namespace App\Http\Controllers;
public function messageList()
{
$message=$this->message->selectMessageByEachUser();
return new MessageCollection($message);
}
どうせチャットルームグループは必要なら、グループに入るユーザーのIDと最新メッセージを保存するチャットルームのテーブルを作る方がいいかも?
メーセージを送信する際、新しいメッセージをテーブルに保存し、後処理はなしで、効率は上がります。