STIを使うとincludesで困る場合がある。
たとえば以下のようなコード。
class User < ActiveRecord::Base
end
class Student < User
has_one :student_detail
end
class Staff < User
has_one :staff_detail
end
この場合、全ユーザーを取得するときにUser.all.includes(:student_detail, :staff_detail)
とは書けない。Userにはそのようなアソシエーションは定義してないので。
以下のようにする。
users = User.all
users.group_by(&:class).each do |klass, records|
associations = {
Staff => [:staff_detail],
Student => [:student_detail]
}.fetch(klass, [])
ActiveRecord::Associations::Preloader.new.preload(records, associations)
end
Rails 4.2.1で確認。
参考にしたページのActiveRecord::Associations::Preloader
の使い方ではうまくいかなかった。上記のpreload
メソッドもドキュメント化されてないようなので、また変わるかも。