EGO-LOG

40代2児の父。主にプログラム学習と開発、仮想通貨、メタバース、たまに関係ないことを綴る。

Laravel投稿サイト構築.64 記事詳細、collectionの結合にハマる

前回

モーダル画面表示を一旦諦めて。

改めて調べると他にもやり方はあるようなので、情報集めつつ保留。

 

■仕様変更~記事詳細表示

やりたいのはTwitterの表示に近い。

投稿の詳細を表示して、紐づくテーマとしたにぶら下がる返信を表示する。

返信は詳細を表示中の投稿のみ可能とする。

 

現状はテーマについてしか返信できないので、返信に対しても返信できるようにする。

 

■返信テーブル項目追加

返信テーブルには親となるテーマIDしかなく、

返信に返信できるようにするためにテーブルに返信先の返信IDを追加する。

-----

$php artisan make:migration replies_add_reply_id --table=replies

-----

$table->bigInteger('reply_id');

-----

$php artisan migrate

 

■コントローラ作成

詳細を表示するためのコントローラを作成

$php artisan make:controller DetailController

 

show関数で詳細表示。

テーマIDと返信IDから表示するデータ一覧を取得する。

 

モデルは既存を使うので作成しない。

 

■ルーティング設定

web.php

Route::resource('/detail', 'App\Http\Controllers\DetailController');

 

■詳細画面に遷移するボタン

テーマと返信にそれぞれボタンを表示して、ボタン押下時に詳細画面に遷移する。

テーマを選択した場合のクエリパラメータは

thread_id = テーマのID

reply_id = 0 とする。

 

返信を選択した場合のパラメータは

thread_id = テーマID

reply_id  = 選択した返信データのID

とする。

 

これによりreply_idが0の場合はテーマが選択されたものと判断する。

 

■詳細画面での一覧表示

twitterでもツイートを選択すると、まずツイートの詳細が表示されて、

ツイートが何かのツイートへの返信である場合、元ツイートも上に表示される。

また、ツイートへの返信も下部に表示される。

ので、それと同様の考え方で選択したデータと関連したデータを取得する。

 

  • テーマのデータを取得
  • 返信データを選択した場合、返信IDのデータを取得
  • 返信IDの返信元データを取得。返信データが無くなるまで遡る。
  • 返信データへの返信データを取得

↑のデータを取得して全部繋げて表示する。

 

■collection のmergeに注意

ここでハマったのが、それぞれ取得したデータはCollectionで取得されるのだが、

先に取得したコレクションに次に取得したデータを追加していく処理。

$col_a = $col_a->merge($col_b);

としても、後のデータで上書きされてしまい想定の結果にならなかった。

さんざん調べて3日ほど沼にはまってようやく解決。

 

$col_a = collect($col_a)->merge($col_b);

 

とすれば望んだ結果になった。

mergeは同じデータを上書きしてしまうので、collectで新しいコレクションを作成することで回避している、という認識。

 

そんなこんなで詳細画面で、テーマに対する返信、

返信に対する返信ができるようになった。

見た目が地味すぎて違いがわからんね。

 

■次回の宿題

  • 詳細画面で書き込んだ時は再表示
  • 再表示の際に、該当の書き込みにスクロールを合わせる
  • テーマと返信で枠を分けて表示
  • 返信のインデントを分かりやすく

 

地道にいきましょうー

続く