joppot

コピペで絶対動く。説明を妥協しない

railsの多対多リレーションでcounter culture を使用する

   

Pocket

countermanytomanythumb

概要

みなさんこんにちはcandleです。
今回は多対多のリレーションが貼られているrailsアプリケーションで、counter cultureを使ってレコード数を数えてみたいと思います。

以下のようなモデルで試してみたいと思います。

erddiagram1

モデルはこんな感じ

class Food < ActiveRecord::Base
  has_many :food_dishes
  has_many :dishes, through: :food_dishes
end

class Dish < ActiveRecord::Base
  has_many :food_dishes
  has_many :foods, through: :food_dishes
end

class FoodDish < ActiveRecord::Base
  belongs_to :food
  belongs_to :dish
end

サンプルデータはこんな感じ

foodsdata
dishesdata

food_dish中間モデルには何もありません。


前提

適当な多対多のモデルがある

SPONSORED LINK


カウントしたいモデルにカラムを追加する

例えば、上の例でいくと、どの料理(dish)がどのくらいの数の食材(food)を使っているか数えたい場合があります。

私の場合はdishモデルにcounter cultureのカラムを追加します。

重要なのは多対多のリレーションでcounter cultureを使用する時は中間モデルを数えるようにします。
dishはfoodを数えるのではなく、中間テーブルのfood_dishモデルを数えるようにします。

それではカラムを追加します。

多対多でcounter cultureのカラム追加は以下のようにします。

bin/rails g counter_culture 親のモデル名 複数形の中間モデル名_count

今回の場合は

bin/rails g counter_culture Dish food_dishes_count

になります。

counter_culture_food_dishes

マイグレーションしましょう。

bin/rake db:migrate

counter_cultureのモデルの設定

後は簡単です。
普段の通り、中間モデルにcounter_cultureの設定を記述します。
中間モデルを開いて、以下を記述します。

counter_culture 親のモデル名

私の場合はfood_dish.rbを開いて、以下を記述しました。

counter_culture :dish

counter_culture_dishsetting

counter_cultureの設定は以上です。

中間モデルを追加してカウントされるかチェックする

試しに中間モデルを追加してdish側でカウントが追加されるか確認します。

今現在、dishの食材カウントは0です。

food_dish_countis_zero

railsコンソールから追加してみます。

bin/rails c
FoodDish.create(dish_id: 1, food_id: 1)

runcreatefood_dish_model
無事作成できました。
データベースを見てみましょう。

updatefood_count

値が上がっていますね。
うまくいきました。

まとめ

counter_cultureはよく使うのですが、多対多ではあまり使用したことがなかったので、まとめてみました。

 - プログラミング