LoginSignup
45
42

More than 5 years have passed since last update.

Railsで1対nでjoinsした列の値をとりたい

Last updated at Posted at 2015-03-03

テーブル構成

  1. Category …カテゴリマスタ
    • name …カテゴリ名
  2. Word …ワードマスタ
    • name …ワード名
  3. CategoryWord…ワードがどのカテゴリに紐づくのか保持
    • category_id
    • word_id

n+1問題

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

こんな感じで全件取得済のマスタの名称を取ってループ中でごにょごにょやったりします。
といってもめっちゃかっこわるいんで他に良いやりかたあるよーってのがあったら教えてください。

45
42
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
45
42