RailsのActiveRecord::FinderMethodsのSQLクエリ発行の有無について調べる

# 環境
Ruby 2.5
Rails 5.2.1

# 目的
Railsでアプリケーションを書く時、このメソッドはクエリを発行するかどうか、度々調べていて、ちゃんと覚えきれていないので、ちょっと調べようと思い、まとめてみることにしました。
ActiveRecord::FinderMethodsに絞ったのは読みやすそうだなと思ったからです。思ったより長くなり完全には調べきれるには気力を消耗しすぎたので、間違っている点があればご指摘頂けると幸いです。

# 参考
[ActiveRecord::FinderMethods](https://github.com/rails/rails/blob/94b5cd3a20edadd6f6b8cf0bdf1a4d4919df86cb/activerecord/lib/active_record/relation/finder_methods.rb)
[Ruby on Rails API](https://api.rubyonrails.org/)

# まとめ表
記事本文はかなり長くなったので結果だけ見たい方はこちら。
（例外発生時のクエリ有無は含んでいません。）

|メソッド名|loadedなインスタンスに対する<br>メソッド呼び出しでクエリ発行しないもの|その他一般的用途で<br>クエリ発行しない条件|例外的な（一般的な用途でない）<br>クエリ発行しない条件|
|---|---|---|---|
|take/take!|○|1. 一度引数なしで当該メソッドを呼び出したインスタンスへの、二度目のメソッド呼び出し。||
|exists?|||下記の場合はクエリを発行しない。（いずれもfalseが返る）<br>1. 引数にfalseを渡した場合<br>2. limit(0)をチェーンしていた場合。|
|find|||下記の場合はクエリ発行しない。<br>1. loadedなのインスタンスに対して、blockつきで呼び出した場合（Enumerableのfindが呼ばれる）<br>2. 引数の先頭に空配列を渡した場合。（空配列が返る）|
|find_by/find_by!|||例外的に下記の場合はクエリ発行しない。<br>1. loadedなインスタンスに対して、blank?がtrueになる引数を渡した場合<br>(ex: users.find_by(nil))|
|first/first!|○|1. 一度引数なしで当該メソッドを呼び出したインスタンスへの、二度目のメソッド呼び出し。|下記の場合はクエリを発行しない。<br>(引数なしの場合はnilが、ありの場合は空配列が返る)<br>1. limit(0)をチェーンしていた場合。|
|second/second!<br>third/third!<br>fourth!/fourth<br>fifth/fifth!<br>forty_two/forty_two!|○|1. 一度メソッドを呼び出したインスタンスへの、二度目のメソッド呼び出し。|下記の場合はクエリを発行しない。<br>1. 内部で呼び出されている数値以下の引数のlimitをチェーンしていた場合。<br>（ex: forty_twoであれば、41以下の引数をもつlimitをチェーンしていた場合)|
|last/last!|○|||
|second_to_last/second_to_last!<br>third_to_last/third_to_last!|○|||

# `ActiveRecord::FinderMethods`にはどんなメソッドがあるのか？
まず`ActiveRecord::FinderMethods`にどんなメソッドがあるか調べていきます。`rails console`で確認すると全部で25個のメソッドがあることがわかります。（読みやすいように並びを変更しています。）

```ruby
pry(main)> ActiveRecord::FinderMethods.instance_methods(false)
=> [:take, :take!, :exists?, :find, :find_by, :find_by!,
 :first, :first!, :second, :second!, :third, :third!,
 :fourth!, :fourth, :fifth, :fifth!, :forty_two, :forty_two!,
 :last, :last!, :second_to_last, :second_to_last!,
 :third_to_last, :third_to_last!,
 :raise_record_not_found_exception!]
pry(main)> ActiveRecord::FinderMethods.instance_methods(false).count
=> 25
```

`:raise_record_not_found_exception!`は例外をあげるメソッドなので、実質24個です。

# `ActiveRecord::Relation`の`loaded?`メソッド
先のメソッドを一つずつ見ていこうと思うのですが、その前に`ActiveRecord::Relation`の`loaded?`メソッドについて少し触れておきます。なぜこのメソッドに触れるのかというと、クエリ発行の有無に関わる場合が多いものだからです。

`loaded?`メソッドはクエリ発行をし、オブジェクトを取得したかどうかを確認するメソッドです。
(参考：[ActiveRecord::Relationとは一体なんなのか](https://doruby.jp/users/whale/entries/ActiveRecord--Relation%E3%81%A8%E3%81%AF%E4%B8%80%E4%BD%93%E3%81%AA%E3%82%93%E3%81%AA%E3%81%AE%E3%81%8B))

`loaded?`メソッドの実態は、`@loaded`インスタンスへのアクセサーの`alias`で、`@loaded`の`true/false/nil`を返すものとなっています。

```ruby
module ActiveRecord
  class Relation
    attr_reader :table, :klass, :loaded, :predicate_builder
    alias :loaded? :loaded
  end
end
```

それでは`@loaded`にどのように値が設定されるかを見ていきます。まず`initialize`時には、`false`がセットされます。

```ruby
def initialize(klass, table: klass.arel_table, predicate_builder: klass.predicate_builder, values: {})
  ~中略~
  # falseが入る
  @loaded = false
  ~中略~
end
```

その後、`load`が呼ばれるとloadedでない場合、内部的には`exec_queries`を呼び出しますが、この中で`@loaded`に`true`が代入されます。

```ruby
def load(&block)
  # loadedでない場合は、クエリが発行される
  exec_queries(&block) unless loaded?

  self
end

private
  def exec_queries(&block)
    skip_query_cache_if_necessary do
      ~中略~
      # 終盤でloadedにtrueが入る
      @loaded = true
      @records
    end
  end
```

そのためloadedなものに対して、`load`をかけてもクエリは発行されません。

一方、`reload`などが呼ばれると内部的には、`reset`と`load`が走りますが、`reset`では`@loaded`に`nil`が代入されるので、次の`load`でクエリが走り、再度`@loaded`に`true`が入ります。


```ruby
def reload
  reset
  load
end

def reset
  ~中略~
  @to_sql = @arel = @loaded = @should_eager_load = nil
  ~中略~
end
```

このようにクエリ実行すべきかどうかの確認を行なっているのが`loaded?`メソッドになります。

それではこれから一つ一つメソッドを下記で見ていきます。

# take/take!
`take`及び`take!`メソッドは下記のようになっています。`take!`は`take`が`nil`の場合に例外をあげる以外、違いはありません。

```ruby
def take(limit = nil)
  limit ? find_take_with_limit(limit) : find_take
end

def take!
  take || raise_record_not_found_exception!
end
```

`take`は引数がある場合は、`find_take_with_limit`を、ない場合は`find_take`を呼んでいます。これらはどのようになっているかというと下記になります。

```ruby
def find_take
  if loaded?
    records.first
  else
    @take ||= limit(1).records.first
  end
end

def find_take_with_limit(limit)
  if loaded?
    records.take(limit)
  else
    limit(limit).to_a
  end
end
```

早速`loaded?`が出てきましたね。

loadedなインスタンスに対して、
・`find_take`の場合は、recordsの最初のインスタンス
　　(`records.first`は`Array#first`なのでクエリ発行しない。)
・`find_take_with_limit`の場合は、recordsの先頭から引数個分の配列
　　(同じく`Array#take`)
を取り出すことがわかります。

一方load済みでない場合は、`find_take`と`find_take_with_limit`で異なります。

`find_take`の場合は、`@take`でキャッシュしており、キャッシュがあればそれを、ない場合は`limit(1)`のクエリ発行することがわかります。
一方、`find_take_with_limit`の場合はいずれの場合も毎回`limit`を発行します。

実際にテストデータで実験してみるとよくわかります。

```ruby
pry(main)> users =  User.where(created_at: 2.months.ago..1.months.ago);
# whereでloadしていないので@loadedはfalse

pry(main)> users.take;
[DEBUG] SELECT  `users`.* FROM `users` WHERE `users`.`created_at` BETWEEN '2018-12-10 15:04:02' AND '2019-01-10 15:04:02' LIMIT 1`
pry(main)> users.take;
# 引数なしの場合、二度目はクエリ発行されない

pry(main)> users.take(2);
[DEBUG] SELECT  `users`.* FROM `users` WHERE `users`.`created_at` BETWEEN '2018-12-10 15:04:02' AND '2019-01-10 15:04:02' LIMIT 2`
pry(main)> users.take(2);
[DEBUG] SELECT  `users`.* FROM `users` WHERE `users`.`created_at` BETWEEN '2018-12-10 15:04:02' AND '2019-01-10 15:04:02' LIMIT 2`
# 引数ありの場合、二度目もクエリ発行される
```

結果的にはクエリ発行されない条件は下記になります。

```
1. loadedなインスタンスに対する、take/take!呼び出し。
2. 一度引数なしのtake/take!を呼び出したインスタンスへの、二度目の引数なしのtake/take!呼び出し。
```

# exists?
`exists?`メソッドは下記のようになっています。

```ruby
 def exists?(conditions = :none)
  if Base === conditions
    raise ArgumentError, <<-MSG.squish
      You are passing an instance of ActiveRecord::Base to `exists?`.
      Please pass the id of the object by calling `.id`.
    MSG
  end

  return false if !conditions || limit_value == 0

  if eager_loading?
    relation = apply_join_dependency(eager_loading: false)
    return relation.exists?(conditions)
  end

  relation = construct_relation_for_exists(conditions)

  skip_query_cache_if_necessary { connection.select_value(relation.arel, "#{name} Exists") } ? true : false
rescue ::RangeError
  false
end
```

結構長いですが、自分なりに翻訳すると下記であろうと思います。

```ruby
 def exists?(conditions = :none)
  if Base === conditions
    # ActiveRecordのインスタンスが渡されたらエラーを吐く。
  end

  # 条件にfalseもしくは、チェーンでlimit(0)を渡していた場合、falseが返る。
  return false if !conditions || limit_value == 0

  if eager_loading?
    # eager_loadしていた場合、eager_loadしたものに対して、exists?する。
    # (eager_load先のものを条件にすることが可能。)
  end

  # relationを構築する。
  relation = construct_relation_for_exists(conditions)

  # 必要であれば、クエリキャッシュをスキップする。(skip_query_cache_if_necessaryの内容をみる限り、block内は実行される。)
  skip_query_cache_if_necessary { connection.select_value(relation.arel, "#{name} Exists") } ? true : false
rescue ::RangeError
  false
end
```

そのため、`exists?`において、例外が出る場合を除いて、クエリが発行されない条件は下記の二つになります。いずれも例外的で普段使わないと思うので、基本的にクエリ発行があると考える方が自然ですね。

```
1. 引数にfalseを渡した場合
2. limit(0)をチェーンしていた場合。
```

実際に実験してみると確かにSQLは発行されていません。

```ruby
pry(main)> User.exists?;
[DEBUG] SELECT  1 AS one FROM `users` LIMIT 1
#　普通にやるとクエリ発行される

pry(main)> User.exists?(false);
# falseを渡すとクエリ発行されない

pry(main)> User.limit(0).exists?;
# limit(0)をチェーンしてもクエリ発行されない

pry(main)> User.all.limit(1).exists?;
[DEBUG] SELECT  1 AS one FROM `users` LIMIT 1
# limit(1)だとクエリ発行される
```

# find

`find`メソッドは下記のようになっています。

```ruby
def find(*args)
  return super if block_given?
  find_with_ids(*args)
end
```

findはこの部分は結構シンプルです。findはblockが渡された場合、Enumerableのfindとして動作します。その他の場合は、`find_with_ids`が呼ばれます。`find_with_ids`は下記のようになっています。

```ruby
def find_with_ids(*ids)
  raise UnknownPrimaryKey.new(@klass) if primary_key.nil?

  expects_array = ids.first.kind_of?(Array)
  return [] if expects_array && ids.first.empty?

  ids = ids.flatten.compact.uniq

  model_name = @klass.name

  case ids.size
  when 0
    error_message = "Couldn't find #{model_name} without an ID"
    raise RecordNotFound.new(error_message, model_name, primary_key)
  when 1
    result = find_one(ids.first)
    expects_array ? [ result ] : result
  else
    find_some(ids)
  end
rescue ::RangeError
  error_message = "Couldn't find #{model_name} with an out of range ID"
  raise RecordNotFound.new(error_message, model_name, primary_key, ids)
end
```

これもざっくり自分なりに翻訳すると下記になります。

```ruby
def find_with_ids(*ids)
  # primary_keyがnilの場合、例外をあげる。

  # 渡されたidsのうち、先頭が配列かつ、空の場合に空配列を返す。
  expects_array = ids.first.kind_of?(Array)
  return [] if expects_array && ids.first.empty?
  # 配列を整理
  ids = ids.flatten.compact.uniq

  model_name = @klass.name

  case ids.size
  when 0
    # 整理した配列の中身が空だった場合、(ex: User.find(nil, nil)を渡した場合)例外をあげる。
  when 1
    # find_oneを呼び、引数が配列だった場合はインスタンス一つの配列で(ex: User.find([2]))、
    # 単数だった場合はインスタンスを返す。
    result = find_one(ids.first)
    expects_array ? [ result ] : result
  else
    # find_someを呼ぶ。
    find_some(ids)
  end
rescue ::RangeError
  # RangeErrorをrescue
end
```

`find_one`では、中でprimary_keyを条件とした`where`と引数なしの`take`が呼ばれており、条件ありのwhereをチェーンしているので、クエリが発行されます。
`find_some`では、中でも同じく条件ありの`where`と`to_a`が呼ばれており、クエリが発行されます。

`find_with_ids`ではメソッドの先頭部分で、`渡されたidsのうち、先頭が配列かつ、空の場合に空配列を返す`ようになっています。そのためこの場合はクエリ発行前に空配列が返るので、クエリは発行されません。実際に実験してみると確認できます。

```ruby
pry(main)> User.find([1],2,3,4);
[DEBUG]   User Load (3.6ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` IN (1, 2, 3, 4)`

pry(main)> User.find([],2,3,4);
# １つ目が空配列だった場合、他の値がなんであれクエリ発行されない
pry(main)> User.find([],2,3,4)
=> []
# 返り値は空配列
```

結論として、`find`において、例外が出る場合を除いて、クエリが発行されない条件は下記になります。

```
1. loadedなインスタンスに対して、blockつきで呼び出した場合（Enumerableのfind）
2. 引数の先頭に空配列を渡した場合。（空配列が返る）
```

# find_by/find_by!

`find_by`及び`find_by!`メソッドは下記のようになっています。`find_by`と`find_by!`の違いは例外時を除くと`take`か`take!`かだけですね。

```ruby
def find_by(arg, *args)
  where(arg, *args).take
rescue ::RangeError
  nil
end

def find_by!(arg, *args)
  where(arg, *args).take!
rescue ::RangeError
  raise RecordNotFound.new("Couldn't find #{@klass.name} with an out of range value",
                           @klass.name, @klass.primary_key)
end
```

この場合は`where`に対して`take`をチェーンしているので、基本的にはクエリが発行されます。しかし、`where`と`take`の性質からある場合についてはクエリが発行されません。

`take`については既に見たので、`where`について見てみましょう。`where`は下記のようになっています。

```ruby
def where(opts = :chain, *rest)
  if :chain == opts
    WhereChain.new(spawn)
  elsif opts.blank?
    self
  else
    spawn.where!(opts, *rest)
  end
end
```

`where`は結構複雑なので深入りはしませんが、一点着目して欲しいポイントがあります。それは`opts.blank?`の場合、`self`を返すということです。ここでは`self`を返すだけなのでもちろんクエリ発行はしません。そして、`take`はロード済みである場合はクエリ発行しないのでした。

つまり、load済みのものに対して、`find_by`の引数に`blank?`なものを渡せばクエリ発行はされません。実際に実験したのが下記です。

```ruby
pry(main)> users =  User.where(created_at: 2.months.ago..1.months.ago).load;

pry(main)> users.find_by(nil);
pry(main)> users.find_by([]);
# Object.blank? == trueなものを渡すとクエリ発行されない
```

使い道は全くないですが、面白いです。

`find_by/find_by!`の場合、クエリが発行されない条件は下記です。

```
1. loadedなインスタンスに対して、blank?がtrueになる引数を渡した場合(users.find_by(nil)など)
```

# first/first!
さて番号系メソッドの`first/first!`です。他の番号系メソッドと違い、`first/first!`だけ引数に数値を取れます。

内容的には下記のようになります。`first!`は`first`が`nil`の場合に例外をあげるだけですね。

```ruby
def first(limit = nil)
  if limit
    find_nth_with_limit(0, limit)
  else
    find_nth 0
  end
end

def first!
  first || raise_record_not_found_exception!
end
```

`first`は引数がある場合とない場合で呼び出すメソッドが異なっています。それらのメソッドは下記になります。

```ruby
def find_nth(index)
  @offsets[offset_index + index] ||= find_nth_with_limit(index, 1).first
end

def find_nth_with_limit(index, limit)
  if loaded?
    records[index, limit] || []
  else
    relation = ordered_relation

    if limit_value
      limit = [limit_value - index, limit].min
    end

    if limit > 0
      relation = relation.offset(offset_index + index) unless index.zero?
      relation.limit(limit).to_a
    else
      []
    end
  end
end
```

`find_nth`は`find_nth_with_limit`を使用しており、なおかつ結果をインスタンス変数に格納していますね。`find_nth_with_limit`を自分なりに翻訳すると下記になります。

```ruby
def find_nth_with_limit(index, limit)
  if loaded?
    # loadedの場合、recordsから特定のindexから特定数取り出す。nilの場合は空配列。
  else
    relation = ordered_relation

    if limit_value
      # limitメソッドを間に挟んでいた場合、limitメソッドの引数からindexを引いたものとfirstの引数の小さい方をlimitとして取る。
    end

    if limit > 0
      # offset_indexとindex数を足して、offsetする
      relation = relation.offset(offset_index + index) unless index.zero?
      relation.limit(limit).to_a
    else
      # limitが0以下の場合は空配列を返す
    end
  end
end
```

上記からfirstのクエリ発行しない条件は下記になります。

```
1. loadedなインスタンスに対する、first/first!呼び出し。
2. 一度引数なしのfirst/first!を呼び出したインスタンスへの、二度目の引数なしのfirst/first!呼び出し。
3. limit(0)をチェーンしていた場合。
```

# second/second!/third/third!/fourth!/fourth/fifth/fifth!/forty_two/forty_two!
さて、first以外の番号系のメソッドですね。`forty_two`だけ少し謎いですね…
（今回初めて知った）

こちらは基本的にはfirstと同じですが、引数は取れません。これらは内部的なメソッド呼び出しの引数が異なる以外は同じなので、サンプルにforty_two/forty_two!をみてみましょう。

```ruby
def forty_two
  find_nth 41
end

def forty_two!
  forty_two || raise_record_not_found_exception!
end
```

やっていることは`find_nth`に特定番号の引数を渡しているだけですね。ほとんと`first`と同じです。そのため、クエリ発行しない条件は下記になります。

```
1. loadedなインスタンスに対する、メソッド呼び出し。
2. 一度メソッドを呼び出したインスタンスへの、二度目の同一メソッド呼び出し。
3. 内部で呼び出されている数値以下の引数のlimitをチェーンしていた場合。
　　　　　　（ex: forty_twoであれば、41以下の引数をもつlimitをチェーンしていた場合)
```

# last/last!
残りも少なくなってきました。お次は`last/last!`です。メソッド内容は下記になります。`last!`は`nil`の場合に例外をあげるだけですね。

```ruby
    def last(limit = nil)
      return find_last(limit) if loaded? || has_limit_or_offset?

      result = ordered_relation.limit(limit)
      result = result.reverse_order!

      limit ? result.reverse : result.first
    end

    def last!
      last || raise_record_not_found_exception!
    end
```

`last`はloadedもしくはlimitかoffsetがある場合と、そうでない場合で挙動が異なります。まず、そうでない場合をみていきましょう。

そうでない場合は内容的にはそれほど難しくなさそうですね。`last`に引数がある場合、引数をlimit数としてセットし、`reverse_order`で内容を取得します。そして、引数なしの場合は、一つ目を、ありの場合は、reverse_orderで取得してきた内容をわざわざ`reverse`メソッドで入れ替えています。おかげで、私たちは`last(2)`と呼び出すと、最後から二つを順番通り（逆順ではなく）得ることができるということですね。そのためこの場合はクエリ発行されそうです。

続いて、loadedもしくは`limit`か`offset`がある場合を見ていきます。この場合は、`find_last`メソッドを呼び出しています。

```ruby
def find_last(limit)
  limit ? records.last(limit) : records.last
end
```

たったこれだけです。超シンプルです。さて、loadedの場合は`Array#last`が呼ばれているのでクエリ発行はやはりされません。それでは`limit`や`offset`の場合はどうでしょうか？。

この場合は、要するにクエリ発行の際に`DESC`で取ったりせずに単純に`offset`や`limit`で取ってきて、それを後ろから特定数取るということをしているだけなのです。実際のクエリを見るとわかりやすいです。

```ruby
[70] pry(main)> User.last;
[DEBUG] SELECT  `users`.* FROM `users` ORDER BY `users`.`id` DESC LIMIT 1`
[71] pry(main)> User.offset(2).limit(3).last;
[DEBUG] SELECT  `users`.* FROM `users` LIMIT 3 OFFSET 2
```

`offset`と`limit`を使っている場合は、`DESC`が入っていませんよね。そのため、`limit`や`offset`がある場合はクエリが発行されます。これらを踏まえるとクエリを発行しない条件は下記になります。

```
1. loadedなインスタンスに対する、メソッド呼び出し。
```

`first`と違って`last`の場合は、インスタンス変数を保持していないので、二度目の呼び出しでもクエリは発行されますし、`limit(0)`をつけてもクエリ発行されます。


# second_to_last/second_to_last!/third_to_last/third_to_last!
ようやく最後のメソッドです。最後まで見てくださって頂き誠にありがとうございます。私もこの時点で既に記事を書き始めて調査含め、6時間が経過しておりそろそろ終わりたいです。笑

メソッド内容を見てみましょう。`second_to_last/second_to_last!`と`third_to_last/third_to_last!`は内部的には引数が異なるだけなので、`second_to_last/second_to_last!`を見ていきます。

```ruby
def second_to_last
  find_nth_from_last 2
end

def second_to_last!
  second_to_last || raise_record_not_found_exception!
end
```

おなじみの`second_to_last!`の場合は、`second_to_last`が`nil`の場合に例外をあげるだけですね。それでは実態のメソッドの`find_nth_from_last`を見ていきます。

```ruby
def find_nth_from_last(index)
  if loaded?
    records[-index]
  else
    relation = ordered_relation

    if equal?(relation) || has_limit_or_offset?
      relation.records[-index]
    else
      relation.last(index)[-index]
    end
  end
end
```

loadedの場合はおなじみですね。普通に`records`から特定インデックスの場所を取り出すだけですね。そのためクエリ発行はされません。

問題は、loadedでない場合です、`if`の部分が少しややこしいですが、これは要するに、現状保持している`relation`の状態が`ordered_relation`と同じかどうか判定しています。`ordered_ralation`では、`order`の指定がなく、`primary_key`が存在する場合は、`primary_key`の`asc`で`order`するように指定しています。それ以外の場合はインスタンスをそのまま返しています。

```ruby
def ordered_relation
  if order_values.empty? && primary_key
    order(arel_attribute(primary_key).asc)
  else
    self
  end
end
```

すなわち先の`if`の戻ると、何かしらの`order`をしているもしくは、`limit`や`offset`をしている場合は、その`order`や`limit/offset`でクエリ発行をし、そこから特定インデックスの場所を取るということをしており、逆に指定がない場合は、`primary_key`の`asc`でレコードを引いてきて、それに対して、特定インデックス分の引数を与えた`last`メソッドを呼び出して、そこからさらに特定インデックスで取り出すということをしています。

```ruby
    relation = ordered_relation

    if equal?(relation) || has_limit_or_offset?
      relation.records[-index]
    else
      relation.last(index)[-index]
    end
```

実際にクエリを見ると、`order`なしの場合は、特定インデックス分の`limit`が入っており、`order`があり`limit`がない場合は一旦全て引いてきていることがわかります。

```ruby
pry(main)> User.second_to_last;
[DEBUG] SELECT  `users`.* FROM `users` ORDER BY `users`.`id` DESC LIMIT 2`
pry(main)> User.order(id: :desc).second_to_last;
[DEBUG] SELECT `users`.* FROM `users` ORDER BY `users`.`id` DESC`
# limitが付いていない。全てのレコードを取得する。
```

全レコードを取ってきているため、レコード数が多いテーブルに対して、気軽に引くと痛い目にあいます。`last`はきちんと`limit`をつけてくれるのですが、`second_to_last`等を使う場合は要注意です。

結果として、クエリを発行しない条件は下記になります。

```
1. loadedなインスタンスに対する、メソッド呼び出し。
```

`last`と同じですね。

# 最後に
以上で終わりです。

想像以上にActiveRecordは奥深く、各メソッドの内部で呼び出されているメソッドは全然調べきれませんでした…

もし異なる点や実験してみたら違う結果が出たり他にクエリ発行しない条件があれば、ご指摘頂けると幸いです。

最後までお読み頂きありがとうございました。