ZEALOTエンジニアブログ

ActiveRecordのfind_by_sqlで関連を事前にロードする方法

Pocket

ActiveRecordで複雑なSQLを使いたいときはfind_by_sqlを使って、ゴリゴリSQLを書いていくんですが、こうして検索されたあるモデルの関連は(とくに何もしなければ)その時点では解決されてなかったりします。(ちなみに、弊社のサービス「Hachikin」でもActiveRecordを使っており、複雑なSQLがあるところではこのメソッドを使ってクエリを投げています。)

例えば、ProjectモデルがUserモデルやCompanyモデルを持っている場合、以下のようにprojects[0].userとした時に、再度SQLが発行されてしまいます。

まぁ、1件くらいだったらいいんですが、検索結果一覧に大量のデータを表示したりすると何度もクエリを発行されるのはなかなかちょっとアレです。

find_by_sqlではなく、普通にArelとかで検索する場合、以下のようにするのですが、find_by_sqlでは以下のようには出来ないっぽい。

そこで、色々調べてみたところfind_by_sqlの場合以下のようにすることで、includesと同じようなことが出来ることが分かりました。(因みに、ActiveRecord 3.1以上の場合)

これで、includesを使った時と同じように3回だけSQLが実行され、userやcompany等の関連もしっかり保たれた検索結果を取得することができました。

答えはStackOverflowにありましたが、あんまり情報がなかったような。意外とfind_by_sqlを使った時に一緒に関連とか使わないんですかね?

Pocket