ActiveRecord::QueryMethodsのselectメソッドについて深掘りしてみた|TechRacho(テックラッチョ)〜エンジニアの「?」を「!」に〜|BPS株式会社エンジニアの「?」を「!」に。CONTACTTOP開発ActiveRecord::QueryMethodsのselectメソッドについて深掘りしてみた開発2019.08.20ActiveRecord::QueryMethodsのselectメソッドについて深掘りしてみたshin1rokシェアツイートブックマークLINEこんにちは。BPSに入社してちょうど1年になりましたshin1rokです。入社時に目標にしていた「TechRachoに技術系の記事を投稿する」を果たすべく、ActiveRecord::QueryMethodsのselectメソッドを深掘りしてみます。5.2.3ローカルにRailsを読むためだけの小さいアプリを作り、RubyMineのコードジャンプとブレークポイントを駆使して探索しました。そもそも(および深掘りの視点)selectメソッドはこのようにModelを拡張する形でAttribute(?)を追加することができます。30このときuserインスタンスにidメソッドは定義されていますが、post_idメソッドは定義されていません。nilなぜだろうか?と思いつつも、仕事でコードを書くときには意識しなくていい部分なので、無視していました。探してみようと思います。Railsダンジョンへ以下を実行した時のselectメソッド以降を呼び出し順に探索していきます。endend※件数を減らすためにlimit(2)しています。block_given?です。ActiveRecordのselectはspawn._select!(*fields)の部分です。spawnは生み出すという意味があるので、spawn._select!(*fields)でSQLのSELECT文を生成しようとしているように見えます。rails/railsよりspawnはselectのレシーバ(User.joins(:posts))のようです。rails/railsより引数をレシーバのselect_valuesに設定して、selfを返しています。rails/railsより_select!のあとなんやかんやがあってrecordsメソッドのloadが呼ばれます。ActiveRecord::Relationは遅延評価されるため。なんやかんやの部分は追いきれませんでした。rails/railsよりまだloadしていないのでexec_queries(&block)が実行されます。&block).freezeです。&block).freezeを入れて、@recordsをreturnしています。このときklassにはUserクラスが入っています。rails/railsよりresult_setはActiveRecord::Resultクラスのオブジェクトで、mapのブロック引数の値はこうなっています。"post_id"=>30}column_typesにはpost_idがどのような型なのかを定義する情報がはいっています。@range=-9223372036854775808...9223372036854775808>}ActiveSupport::Notifications.instrumenter.instrumentはブロックで渡された内容の実行時間を計測します。post_id').limit(2)とイコールになります。&block)がActiveRecord::Relationオブジェクトの各要素です。30ここまででpost_idをUserモデルのインスタンスに割り当てている処理が特定できたので今回の探索はここまでにします。pairsendActiveRecord::Relationオブジェクトを作らない分速くなるので、こちらの方が良かったですね。Storageを使ってはいけない(翻訳)#Tags#会社紹介#自社サービス#勉強会#Rails#PHP#デザイン#実績#週刊RailsウオッチCONTACTお気軽にご相談ください。(翻訳)CONTACTTechRachoでは、パートナーシップをご検討いただける方からのご連絡をお待ちしております。お気軽にご意見・ご相談ください。