まず前提として
今回のいいね機能を実装するにあたり、1から解説すると長くなりすぎてしまうので、以下の条件を前提とします。
(アプリ開発を少しでもやっていれば既知かもしれません)
- User と Book のテーブル(モデル)が存在する
- Userモデルにはdeviseのgemを導入している:ログイン機構
この時点で、何を言っているかわからない場合は実装するのが難しいので、まず別の記事などで勉強することをおすすめします。
実装手順
それでは、いいね機能の実装手順を解説していきます!
少し長くなりますので、覚悟してお付き合いください。
いいね用のテーブルを作成
まずは”いいね”用の Favorites テーブルをマイグレーションで作成していきます。
これは、いわゆる中間テーブルと呼ばれるやつで、user_id と book_id のカラムしか持ち合わせないテーブルです。
これだけで”いいね”の数や関係性を表現できるんです。
マイグレーションファイルなどを生成
最初に以下のコマンドで、テーブルを作成するマイグレーションファイルを自動生成しましょう。
rails g model favorites
マイグレーションファイルを編集
生成されたマイグレーションファイルを編集します。
Favorites テーブルには、user_id と book_id 、あとはデフォルトのタイムスタンプ系のカラムのみなので、以下の内容を追記します。
追記したコードを少し解説しておきます。
references とは
これは、他のテーブルの主キーを参照する意味合いで、:user の指定で user_id のカラムを作成してくれます。
加えて自動的にインデックスの定義をしてくれます。
インデックスを定義すると、そのキーを用いてレコード検索などする時の速度が速くなる効果があります。
foreign_key とは
これは外部キーのことで、対象テーブルに存在するキーしか入力できないようにする制限です。
例えば、User の id = 1 のユーザー(レコード)が存在しないのに、Favorites に user_id = 1 のレコードを登録しようとするとエラーになります。
テーブル作成
マイグレーションファイルの編集が完了したので、次のコマンドで実際にテーブルを作成します。
rails db:migrate
モデルの定義を追加
今回新たに作成した Favoriteモデル、それに関わる User、Bookモデルについてアソシエーションの記述をしていきます。
パスを作成(routes.rb)
Book に対する”いいね”なので、books の配下としてパスを設定します。
こうすることで、どの Book に対する”いいね”なのか id によって判別がつくようになります。
resources :books, only: [任意のメソッド] do
resource :favorite, only: [:create, :destroy]
end
※ちなみに、”only” のくだりは書いても書かなくても、動くには動きます。(書いた方が無駄なパスが生成されなくて良いです)
この状態で rails routes コマンドを打つと、favoriteのパスが追加されているのが確認できます。
コントローラーにメソッドを定義
まずは Favorite用のコントローラーを生成しましょう。
rails g controller favorites
まっさらで生成されたコントローラーに、先ほど routes.rb で定義したメソッドを追記していきます。
それぞれのメソッドについては、次のことを覚えておきましょう。
- createメソッド = HTTPリクエストのPOST
- destroyメソッド = HTTPリクエストのDELETE
ビュー(画面)を作成
今回は Book の”いいね”を作っていくため、Book一覧画面に”いいね”用のリンクを追加します。
該当部分のコードをピックアップすると以下のような感じです。
コントローラーで favorite を “includes” している箇所がありますが、これによって favorite をメモリに展開させています。ビュー側の、faborite.size で”いいね数”を取得するためにこれを付けています。
(includes しなくても動きますが、都度クエリ発行して効率が悪くなってしまう。。という理由もあります)
この時点ではまだ”いいね”を登録する処理を入れてないので、「いいね済」のリンクは画面に出てきませんが、「いいね」のリンクは画面に表示されることが確認できます。
コントローラーの中身を記述
再びコントローラーに戻り、createとdestroyの処理を記述していきます。
ひとまずこれで”いいね機能”が動作するようになりました!
後編では改善版を紹介!
このままだと”いいね”を押すと一覧画面を再読み込みするので、スクロールしていると元に戻ってしまいます。
これを解決する方法の1つとして非同期通信で処理する方式があります。
後編ではこれを実装していきましょう。
見た目も”いいね”が文字のままでイマイチなので、改善する方法を解説します!
まとめ&おまけ
まとめ
いいね機能の実装手順は以下の通りでした。
- 前提として、UserモデルとBookモデル作成済
- Favoriteモデルを作成
- パスを追加
- ビューを整形
- コントローラーに処理を追記(idの渡し方やレコード検索を工夫する)
おまけ
ここでは少しリファクタリングの紹介をします。
実は上で紹介したコントローラーの記述について、createの部分が少し短くできるんです。
モデルに対してcreateメソッドを使うと、1行の記述でレコードを作成してくれます。
これは、Favorite.newとFavorite.saveを一挙にやっている仕組みなので、実質やっていることは変わりません。
今回のように、レコード作成時のパラメータを1行で書けてしまう場合は、createメソッドを使う方式の方がスッキリしますね!
コメント