同名の関連先がある場合のincludes

ActiveRecord 3.1.1 でのおはなし。

class Game < ActiveRecord::Base
  belongs_to :home, :class_name => "Club", :foreign_key => 'home_id'
  belongs_to :away, :class_name => "Club", :foreign_key => 'away_id'
end
class Club < ActiveRecord::Base
  has_many :japanese
end
class Japanese < ActiveRecord::Base
  belongs_to :club
end

上記のようにモデルClubに複数属するGameのようなモデルがあり、属したClubが関連先japaneseをもつとき

Game.includes(:home => :japanese, :away => :japanese).each do |game|
  game.home.japanese
  game.away.japanese
end

とすると、includesしているのに何度もSQLが発行されてしまう。どうも同名の関連先(ここではjapanese)があるとうまく動かないみたい。

そこで、

class Club < ActiveRecord::Base
  has_many :home_japanese, :class_name => 'Japanese', :source => :japanese
  has_many :away_japanese, :class_name => 'Japanese', :source => :japanese
end

のように別名を付けてあげる。

Game.includes(:home => :home_japanese, :away => :away_japanese).each do |game|
  game.home.home_japanese
  game.away.away_japanese
end

そうすると、まとめて読み込んでくれるので速度が上がる。