Railsの学習(7日目)
7日目
いいね機能を搭載する
ユーザーがいいねした投稿ページを作る。
「どのユーザー」が「どの投稿」をいいねしたかを記録するために、「user_id」と「post_id」の二つのカラムを持つ「likesテーブル」を作成する。
rails g model を用いてマイグレーションファイルを作成し、準備ができたらrails db :migrateでデータベースに変更を反映させる。
いいねのデータはuser_idとpost_idの両方がないといけないので、バリデーションをかけておく。処理はpresence: trueで良い。
ログインしているユーザーがその投稿にいいねをしたか表示する。逆にいいねをしていなかったら、いいねをしていないと表示するようにする。
そのためにはログインしているユーザーがその投稿にいいねした投稿が存在するかどうか、ログインしているuser_idとpost_idが合致しているデータを、likesテーブルからfind_byを用いて探す必要がある。これをif文で書くことで、いいねしているかしていないかの条件分岐をさせる。
いいねボタンの準備
ここからいいねしたり、いいねを取り消したりできるようにする。まずはlikesコントローラを作成してLikeデータを作成するためのアクションを作成する。
今までコントローラは「rails g controller」コマンドで自動生成してきた。コマンドを用いるとビューファイルも自動生成されるが今回はビューファイルは必要ないので、今回はコントローラファイルを手動で作成する。
作り方としてはcontrollerフォルダに「likes_controller.rb」を作成することで作成される。
作成したコントローラに新たにLikeデータを作成するためにcreateアクションを作成する。createはデータベースにデータを作成するアクションなので、postで定義する。
今回はURLの部分は「どの投稿をいいねしたか」という情報を送信するために、「likes/:post_id/create」する。
これで作ったcreateアクションの中身を完成させ、そのアクションへのリンクを「いいね!」ボタンとして投稿詳細ページに表示させる。
createアクション内では新たにデータを作成後、投稿詳細ページへリダイレクトするようにする。user_idは現在ログイン中のユーザー、post_idは開いた投稿記事に応じたidにする。
作成したcreateアクションへのリンク(/likes/#{@post.id}/create)をlink_toを用いて投稿詳細ページに追加する。今までは「いいね!していません」と表示していた部分を、「いいね!」するためのリンクに書き換える。つまり「いいねしていなければ、いいね!というリンクと機能を表示するようにする」ということ。
いいね取り消しボタンを作る
いいね取り消し機能を作るにはlikesコントローラにdestroyアクションを用意する。
destroyアクションでは受け取ったログイン中のidと投稿内容のidをもとに削除すべきlikeデータを受け取り、削除する。
destroyアクションへのリンクを投稿詳細ページに追加し、今までは「いいね!済み」と表示していた部分を、「いいね!」を取り消すためのリンクに書き換えます。
Font awesomeを使っていいねボタンをアイコンにかえる
font awesomeを利用するには<head>タグがひつようになる。あとはapplication.html.erbに<link>を作って埋め込んでいく。詳しいやり方は(HTML & CSS 学習コース 中級編)
これはあくまで読み込みなので、ここから実際にアイコンに変えていく
左の図のようにHTMLを書き、show.htmlにリンクを埋め込んだが、link_toメソッド内にHTML要素を記述するとうまく反映されてくれない
この場合は<%= link_to("URL") do %>HTML要素<% end %>とすることで実行できる。
つまり2個上のハートマークを表示するコードを参考にしつつ、上の画像のやり方を応用すれば、下の画像の通りになる。要は実行したいHTML要素をlink_toメソッドで囲うということだ。
いいねの数を取得する。
いいねの数を数えるにはSQLでも用いたCOUNTメソッドを使う。これは配列の要素数を取得するメソッドだがデーブルのデータ数を取得するのにも役立つ。
いいねした投稿を表示する。
今回はユーザーに関するページを作成するのでlikeコントローラではなくusersコントローラにお気に入り投稿一覧ページを表示するためのlikesアクションを作っていく。
ルーティングのURL部分はshowアクションと同様に、どのユーザーに関する情報を表示するかを判断するために「users/:id/likes」これでこのURLでアクセスできるrootingを作成できた。そのユーザーがいいねしたページというニュアンスが伝わりやすいURLだねぇ。実際には[params:id]になると思われる。
いいね一覧のページを表示する。
viewページ用いるための変数をlikesアクション内で定義する。whereメソッドを用いてそのユーザーに関するデータをlikesテーブルから取得し、変数@likesに代入する。これでビューページで変数を使うことができる。
likesアクション内で定義した変数@userと@likesを用いて、ビューも完成させたい。各投稿を1つずつ表示するためには、@likesに対してeach文を用いて、likeに紐付いているpostを繰り返し表示させる。