テーブル構成
- Category …カテゴリマスタ
- name …カテゴリ名
- Word …ワードマスタ
- name …ワード名
- CategoryWord…ワードがどのカテゴリに紐づくのか保持
- category_id
- word_id
n+1問題
アソシエーションが作成されてあってCategoryWordからCategoryの名称を取る場合は以下の通りになるかと
CategoryWord
def self.get_first_category_name
CategoryWord.first.category.name
end
ただしこの場合だとCategoryWordの件数分、CategoryモデルにもSELECT分が実行されるため、
n(CategoryWordの件数分のCategoryモデルの参照) + 1(CategoryWordモデルへの参照)が起きてしまいます。
そのため、本来SQLで行っているような結合を明示的に行う必要があります。
やりかた
ActiveRecordクラスに存在するattributesメソッドを使い、結合先のカラムを取得する。
CategoryWord
def self.get_first_category_name
CategoryWord.joins(:category).select("categories.name").first.attributes
end
n+1問題で困るのは大体allとかwhereで取得したレコードに対してeachでぐるぐるまわすパターンなので、それはいかになります。
CategoryWord.each
CategoryWord.joins(:category).select("categories.name").each do |cat|
p val.attributes["name"]
end
こんな感じで全件取得済のマスタの名称を取ってループ中でごにょごにょやったりします。
といってもめっちゃかっこわるいんで他に良いやりかたあるよーってのがあったら教えてください。