Rails の find_by メソッドのドキュメントを読んでみる

find_by

find_by メソッドでは、以下のように、内部で where メソッドが呼ばれて、引数で渡した条件にマッチしたレコードを探して、最初の1件を返すようになっている。

また、条件に合うレコードがなかった場合は nil を返す。

f:id:matt-note:20181022103537p:plain

 参考:ActiveRecord::FinderMethods

 

where

where メソッドは、引数で渡した条件によってレコードを探して、結果を返す。引数をハッシュで渡した場合、キーと値で渡した条件にマッチしたレコードを探す。

f:id:matt-note:20181022104254p:plain

f:id:matt-note:20181022104424p:plain

参考:ActiveRecord::QueryMethods

 

find_by と where で何が違うのか

Google で検索して見つけた説明は、以下の通り。たしかに、ドキュメントを読むと、find_by メソッドでは "Finds a first record" と書いているのに対して、where メソッドでは "Returns a new relation" と書かれている。

find_byメソッドで取得できるのは1件のみです。もし条件に合うモデルが複数あった場合は最新の1件が取得されます。

whereは条件に合うモデルを複数取得したい場合に使います。

参考:find、find_by、whereなどモデルを取得する方法まとめ | JavaからのRuby on Rails入門

 

take

上記の find_by メソッドのソースコードを読んでみると、where(arg, *args).take と、whereメソッド呼出し後に take メソッドを呼び出している。take メソッドについての説明は以下の通り。"Gives a record" と、レコードを一件返すメソッドとなっている。発行するSQL文の中では、デフォルトで LIMIT 1 を指定している。

f:id:matt-note:20181022110836p:plain

 参考:ActiveRecord::FinderMethods

 

まとめ

find_by メソッドは、where メソッドを呼び出して条件にマッチした集合を取り出してから、take メソッドを呼び出して、その集合からレコードを1件取得するようになっている。