その記事にどれくらいのオピニオンが集まっているのかを表示したいと思います。例えばこんなふうにアイコン付きで数字があればなんかカッコいいですよね。
counter_cacheとはRailsの持っている集計機能のひとつです。たくさんのコードを書かずに、かんたんに実装できるのがRailsらしい特徴になっています。
具体的に言うと「関連する子モデルレコードの数を集計して、親モデルレコードに集計結果を保存してくれる機能」ということになります。これを少しのコードで実現することができます。
今回の例で言うと、オピニオンが作られるたびにクリップのopinions_count属性のカウントがアップします。
では、実装方法を説明していきます。まず、親モデルにカウンター用の属性を追加します。この時の属性名ですが、
モデル名+s_counter
とするという決まりがあります。今回の場合は、モデル名がOpinionなのでopinions_counter になります。
以下コマンドを実行して下さい。
# ターミナル
$ rails g migration add_opinions_count_to_clip opinions_count:integer
# => migrationファイルが作成される
次に、作成されたmigrationファイルにdefault: 0と追加します。
# migrationファイルの編集default: 0を追記
add_column :clips, :opinions_count, :integer, default: 0
migrationファイルを編集した後はrails db:migrateを実行して、変更を反映させましょう。
# ターミナル
$ rails db:migrate
counter_cacheを使うには、親モデルに属性を追加するだけではなく、子モデルにcounter_cache: trueという記述を追加する必要があります。opinion.rbを以下のように編集して下さい。
# opinion.rb
belongs_to :clip, counter_cache: true
これで、counter_cacheが使えるようになりました。
では、実際にカウンターが機能しているかターミナルで試してみましょう。コンソールを立ち上げて、以下を参考に試してみて下さい。まずはユーザーとクリップを用意します。
$ rails c
# ユーザーを用意
> user = User.first
# クリップを用意
> clip = Clip.first
クリップの詳細を見ると、opinions_countは0となっているはずです。
> clip #=> .... opinions_count: 0
次にユーザーがそのクリップにオピニオンを作成してみます。
> user.opinions.create(clip: clip, title: "test", body: "test opinion")
クリップの詳細を再度見てみるとopinions_countは1に増えていると思います。
> clip #=> .... opinions_count: 1
これで、opinions_countの追加はうまくいっていることが確認できました。
クリップに、ユーザークリップカウンターも追加してみましょう。
無料ビデオ講座のお知らせ
Skillhub [スキルハブ]では無料の動画講座を多数公開しています。他校だと数万円するような講座が無料で受講できます。