前回の備忘録に引き続き、日報管理システムの機能拡張を試みる。前回、他人の日報に「いいね!」のリアクションをする機能を追加し、日報一覧画面および日報詳細にそのいいね数を表示させるように変更したが、そのいいね数をクリックすることで、誰がその日報に「いいね!」をしたのか一覧で表示する画面を表示させたい。
がんばっていこー
1 モデルの修正(データベースへのテーブル追加)
現状、このシステムのデータベースにはEmployeeテーブルとReportテーブルの2つしか存在しない。この2つのテーブルだけで誰がどの日報にいいねしたかを管理するのは難しいので新たにLikeテーブルを作成する。
前回はテーブルの新規作成はせず、既存のReportテーブルにlike_countの列を追加する作業だったので、MySQLからALTER TABLEコマンドを使って修正したが、今回は新規作成なので、直接Javaファイルでモデルを書き込む。これをサーバーにアップすればHibernateというフレームワークツールが勝手にデータベースとやりとりしてテーブルを作成してくれる。
続いて、Javaサーブレットの作成。前回は、いいね!ボタンをクリックすると、ReportLikeサーブレットにパラメータを飛ばして、いいね数を+1する処理だけして一覧ページへリダイレクトさせるようにした。このReportLikeサーブレットにそのまま加筆しても動作的には問題ないけれども、今回はLikesCreateサーブレットを新規作成して、Reportとは別のパッケージの中に保存しようと思う。単純に、その方が後でまたいじる時に構造が見やすい。
新規のLikeをインスタンス化してデータベースに登録する処理を記入。like_countを1加える処理は、前回のをそのままコピペしてきた。
ここまでやったら動作確認をしてみる。
一般花子さんの日報詳細ページでいいね!すると
無事、いいね成功。ここまでは前回同様。問題はちゃんとLikeテーブルにいいねの情報が保存されているかってことなので、ターミナルからMySQLを開いてチェックしてみる。
daily_report_systemのデータベースにlikesテーブルが加わって、ちゃんと先ほどのいいねに関する情報が保存されてる。やったぜ。
2 ビューの作成
誰がどの日報にいいねを押したかをデータとして管理できるようになったので、実際にそれを一覧として表示できるようにする。まず、最終的に表示するためのページをHTMLで作っておく。
もちろん、このビューファイルを作っただけで表示はできない。表示するためのデータを渡す処理を作ってないから。というわけで次、コントローラーの作成。
3 コントローラーの作成
ある日報に対していいねした人の一覧を表示するためには、データベースのLikeテーブルから条件に一致する情報を抽出する作業が必要なので、単純に日報一覧ページからいいね一覧ページへリンクするだけじゃ対応できない。なので、データ処理をするLikeShowサーブレットを新しく作って、そこを経由していいね一覧ページへ飛ぶようにする。
が、その前に、「Aという日報に対してのいいね!だけをLikeテーブルから抽出」みたいな都合のいいメソッドは用意されていないので、これは自分で定義しておくしかない。よってまず先ほどのLike.javaに加筆する。
“getItsAllLikes”というクエリを新規追加した。reportと言うパラメータ名でReport型のデータを渡せば、それと一致するデータを含むLike型のデータを抽出して返してくれる文。
それから、先に日報一覧ページと日報詳細ページにリンクを付けておく。パラメータとして、クリックされた日報のid(report.id)をLikeShowサーブレットに飛ばすようにする。
いよいよLikesShowサーブレットの作成。
リンク元から受け取ったreport.idをもとに、Report型の変数rを宣言。先に作ったgetItsAllLikesのクエリにrをパラメータで送って、rを含むLike型のデータを全て抽出して、List型の変数likesに格納。このlikesとrの情報を送ってやれば、先ほど作成しておいたビューファイルがやっと機能するようになる。
テストしてみる。
いいね!列の表示数がリンク(青色)に切り替わっております。クリックすると・・・
無事、いいねした人の一覧が表示された!
4 いいね回数の制限
これで今回の機能拡張は達成されたわけだが、調子に乗ってもうちょっとやっちゃう。せっかくLikeテーブルを作ったので、前回に少し触れた「一つの日報につき、いいねは一人一回」の制限を加えてみようと思う。
getItsAllLikesのクエリと同じ要領で、複数条件のクエリを作ることも可能。”getMyLikesCount”という名前でクエリをつくり、指定したreportとemployeeを同時に含むlikeの数を返してもらえるようにした。
日報詳細ページへのリンクをクリックした時に、このクエリを使って、該当の日報にログイン中の社員がいいねした数を求めて、my_like_countという変数に入れてビューファイルに渡す。
そしてビューファイルで、表示の仕方をif文で分岐させる。これまでは、ログイン中の社員と日報を書いた社員のidが違う場合は例外なくいいねボタンを表示させていた。(login_empoyee.id != report.employee.id)しかし、ここにAND条件を加えて、ログイン中の社員が日報を書いた社員ではなく、且つ、my_like_countが0の時だけいいね!ボタンを表示させるようにする。(login_employee.id != report.employee.id && my_like_count == 0)
my_like_countが0以外の時、すなわち、既にその日報にいいね!をしてる場合は、そのことを知らせるメッセージを表示させる。
先ほどいいねした日報の詳細ページを見てみる。
いいねボタンが消えて、代わりにメッセージが表示された。成功でやんす。これは後でいいね!を取り消す機能をつけたい時にも応用できるな。
というわけで、今回はこんな感じ。前回に比べるとだいぶ歯応えあったな・・・