Ruby
ActiveRecord
SQL
RubyOnRails

ActiveRecord::Relationのメソッドが何を返すのか

ツッコミ大歓迎です

記事のターゲット

Railsを触り始めたばかりの人(僕)
ActiveRecordをなんとなくで触ってた人(僕)
ActiveRecordのメソッドが何を返すのか知らなくて知りたい人(僕)

ORMの勘所

ActiveRecordは言わずと知れたORMです
ORMは使い方を知らないと
「不要なクエリを発行したり(無駄なクエリ発行)」「N+1問題が発生したり(無駄なクエリ発行)」「全件取ってきてしまったり(無駄なクエリ発行)」
とりあえず無駄だらけになってしまいます

なぜ無駄なクエリが発行されているか深掘りするために必要な観点は
いつクエリ発行されるかだと思います
それはActiveRecord::Relation配列やオブジェクトに変わるとき!
と言い換えることができますね

  • ActiveRecord::Relationを返す = クエリは発行されていない
  • 配列やオブジェクトを返す = クエリが発行されている

本題

まずはActiveRecordのメソッド群が何を返すか?を調べます
Railsガイドを眺めると以下のように記載してありますね

検索メソッドはwhereやgroupと行ったコレクションを返したり、ActiveRecord::Relationのインスタンスを返します。また、findやfirstなどの1つのエンティティを検索するメソッドの場合、そのモデルのインスタンスを返します。

なるほど。わからん

…自力で潜ってみましょう

ActiveRecord::Relationを返すメソッド

  • all
  • scope (実装でnilを返すとallと同様になる)
  • select (使い方次第)
  • group
  • order
  • reorder
  • unscope
  • joins
  • where
  • rewhere
  • having
  • limit
  • offset
  • lock
  • none
  • readonly
  • create_with
  • from
  • distinct
  • extending
  • reverse_order
  • includes
  • eager_load
  • preload
  • references
  • uniq
  • merge
  • except
  • only

配列やオブジェクトを返すメソッド(多すぎるので一部割愛)

  • select (使い方次第)
  • find
  • find_by
  • take
  • first
  • last
  • second
  • third
  • fourth
  • fifth
  • forty_two
  • exists?
  • ids
  • pluck
  • sum
  • maximum
  • minimum
  • average
  • count
  • find_each
  • find_in_batches
  • to_a etc...
  • 各種delegateされているArrayメソッド

まとめ

ActiveRecord::Relationを返すメソッドはSQL元来使えるものに近しい名前だった
配列やオブジェクトを返すメソッドは「見つける」とか「取る」みたいなアクションが多かったり集計関連だったりした
また、配列のメソッドを呼び出すとクエリが発行されるのはまさに結果が必要になったタイミングなのだろう

検索メソッドはwhereやgroupと行ったコレクションを返したり、ActiveRecord::Relationのインスタンスを返します。また、findやfirstなどの1つのエンティティを検索するメソッドの場合、そのモデルのインスタンスを返します。

要約するとRailsガイドの言い方になりました

参考

ActiveRecord::Relationとは一体なんなのか
Railsガイド Active Record クエリインターフェイス
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/relation.rb