こんにちは、Nanayakuです。
今回は、いいね機能の追加について解説していきます。
目次
モデルの作成
いいね機能を追加するために、まずfavoriteモデルを作成します。
favoriteモデルは、表のようなテーブルになります。
Favoritesテーブル | ||
ID(integer) | user_id(integer) | topic_id(integer) |
1 | ||
2 |
以下の作成・読み込みコマンドを実行します。
$ rails g model favorite user_id:integer topic_id:integer
$ rails db:migrate
favoriteモデルのアソシエーション
favoriteモデルのはUser・Topicモデルに対して、以下のアソシエーションを持ちます。
- UserとTopicは複数のFavoriteを所有します。
- FavoriteはUserとTopicをそれぞれ1つづつ所有します。
それぞれのモデルに
- userモデル(app/models/user.rb)には「has_many :favorites」
- topicモデル(app/models/topic.rb)には「has_many :favorites」
- favoriteモデル(app/models/favorite.rb)には「belongs_to :user belongs_to :topic」
が追記します。
コントローラーの作成
$ rails g controller favorites
このコマンドでfavoritesコントローラーを作成します。
createアクションについて解説します。
「favorite = Favorite.new」は、Favoriteクラスのローカル変数favoriteを生成しました。
「favorite.user_id = current_user.id」は、ログインしているユーザーのidを格納しています。
「favorite.topic_id = params[:topic_id]」は、いいねしたtopicのidを取得しています。これは、Viewのリンクをクリックした時に、取得できるように下のリンク作成で書き方を説明しています。
そして、save(保存)できたかを条件分岐でフィードバックで表示します。
ルーター・リンクの作成
ルーターは「post '/favorites', to: 'favorites#create'」と追記します。
ハートマークのリンクを画像のように作ります。
「favorites_path(topic_id: topic.id)」の部分は、ルーターにあるfavorites#createアクションにへ遷移した時に、いいねしたtopicのidを取得することを表しています。
また、「method: :post」でルートを指定しています。
これにより、お気に入り解除をやりやすくなります。
いいね一覧画面の作成
いいね一覧を表示するfavoritesコントローラーにindexアクションを作成します。
ログインしているユーザーがいいねしているtopicを取得してViewで表示するので、ルーターのHTTPメソッドはGETになります。
よって、ルーターに以下のコードを追記します。
get 'favorites/index'
いいね一覧のアソシエーション設定
いいね一覧を作るために、以下のアソシエーションを追加します。
has_many :favorite_topics, through: :favorites, source: 'topic'
これは、through(中間テーブル)を使うことで、ログインしているユーザーがいいねしているtopicを全て取得することができます。
後は、いいね一覧を表示するViewを作成します。
いいねの表示変更
いいねのハートマークの表示変更は、画像のような条件分岐になります。
1つ1つ解説していきます。
アソシエーション
topicモデルに「has_many :favorite_users, through: :favorites, source: 'user'」を追記します。
上記の「いいね一覧のアソシエーション設定」で説明通りで、表示しているtopicをいいねしている全てのユーザー(id)を取得します。
条件分岐
if !topic.favorite_users.include?(current_user)
「if !条件式」は条件式が偽だった場合に処理をします。
これと同じもので「unless」があります。
「unless topic.favorite_users.include?(current_user)」も同じ意味になります。
「include?」は存在しているか確認するときに使います。
条件式は、「このtopicにログインしているユーザーのid(favorite_users)が存在しなかったら」と言う意味になります。
存在しなかった場合、線のみのハートマークを表示し、クリックするとfavoriteテーブルに追加されます。
ここまでが、青枠の中の処理です。
次に、存在していた場合、赤色のハートマークを表示し、クリックするとfavoriteテーブルからカラムを削除する処理を追記します。
コントローラーで、削除する(destroy)アクションを作成します。
「Favorite.find_by(params[:topic_id]).destroy」は、取得したtopic_idを含むカラムを削除する処理です。
ルーターは「delete '/favorites', to: 'favorites#destroy'」と設定します。
Viewは画像の青枠と同じようになり、HTTPメソッドが”delete”になっています。
これで、いいねをしていると赤いハートが表示され、いいねしていないと色無しのハートが表示されます。
参考
いいねのカウント
いいねされた数を表示する方法は、上記のいいねの表示変更の条件分岐の下に以下のコードを追記します。
<%= topic.favorite_users.count %>
これで画像のようにいいねされた数を表示できます。
自分が犯した失敗
アソシエーションをしっかり理解していなかったため、commentからfind_byを使っていいねされた数を表示しようとしましたが、topic/indexアクションにcommentを定義していないため、表示できませんでした。
アソシエーションでテーブルを連携できるため、topic.カラム名.countで、そのカラムの数を取得できます。
テーブルを1つ1つ独立していると考えていたのがダメでした。
おすすめ参考資料
- コメント登録機能の追加 - (1)コメントの表示
- Railsドキュメント・count
- 2.4 has_many :through関連付け
- 【Rails】いいね!の数を表示する方法
- 【Rails】DBのデータをビューで使用する
- 【初心者向け】丁寧すぎるRails『アソシエーション』チュートリアル【幾ら何でも】【完璧にわかる】🎸
最後に
備忘録がわりに作ったので、間違っている所とかあったら、コメントくれると嬉しいです。