Ruby / Rails

いいね機能の追加

2019年7月12日

こんにちは、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?」は存在しているか確認するときに使います。

include? (Array)

条件式は、「この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つ独立していると考えていたのがダメでした。

 

おすすめ参考資料

 

最後に

備忘録がわりに作ったので、間違っている所とかあったら、コメントくれると嬉しいです。

-Ruby / Rails
-

© 2024 Nanayaku blog Powered by AFFINGER5