どうしても AR の query methods だけでは要求を満たせない場合の最後の手段として、find_by_sql
メソッドがあります。皆さんよく使ってると思うのですが、戻り値のレコードからさらに association をロードしようとすると N+1 になるケースがあります。かといって
User.preload(:comments).find_by_sql(sql)
のようにしても期待通りには動きません。単純に preload
部分が無視されるだけです。
ではどのように書いたらよいでしょうか。
次のように書くと期待通りに動きます(Rails 4.2.1 で試しています)。
records = User.find_by_sql(sql)
ActiveRecord::Associations::Preloader.new.preload(
records, :comments
)
records # comments が preload されている
:comments
の部分は、通常の preload
と同じように、配列やハッシュを指定できます。
これで N+1 の心配をせずに済みそうです。