LoginSignup
13
10

More than 5 years have passed since last update.

【Rails】findとfind_byとwhereの使い分け

Last updated at Posted at 2018-10-26

データを探して取って来たい

  1. 「id」がわかっていて、ひとつだけ取りたい    → findメソッド
  2. 「id」がわからないが、それ以外の情報がわかっている。ひとつだけ取りたい    → find_byメソッド
  3. ひとつの情報で、複数のデータを取りたい    → whereメソッド

findメソッド

User.find(3)

・検索できるのは「id」のみです
・検索にかかったひとつのデータを取得します
・検索に該当するものがなかった場合はActiveRecord::RecordNotFoundを返します

pry(main)> User.find(3)
  User Load (0.6ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 3 LIMIT 1
=> #<User:0x00007f894b349aa0
 id: 3,
 email: "〜",
 crypted_password: "〜",
 salt: "〜",
 created_at: 〜,
 updated_at: 〜,
 reset_password_token: 〜,
 reset_password_token_expires_at: 〜,
 reset_password_email_sent_at: 〜,
 access_count_to_reset_password_page: 〜,

 id = 3のデータが取得できました

pry(main)> User.find(8)
  User Load (0.5ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 8 LIMIT 1
ActiveRecord::RecordNotFound: Couldn't find User with 'id'=8

id = 8のデータが存在しておらず、ActiveRecord::RecordNotFoundが返っています。
コードによっては、この返り値で処理が止まってしまうことがあります。要注意です。

find_byメソッド

User.find_by(name: "morikuma")

・「id」以外でも検索できます
・複数のデータが該当する場合、検索にかかった一番最初のデータをひとつだけ取得します
・検索に該当するものがなかった場合はnilを返します

pry(main)> User.find_by(name: "morikuma")
  User Load (0.6ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 3 LIMIT 1
=> #<User:0x00007f894b349aa0
 id: 4,
 name:""morikuma"
 email: "〜",
 crypted_password: "〜",
 salt: "〜",
 created_at: 〜,
 updated_at: 〜,
 reset_password_token: 〜,
 reset_password_token_expires_at: 〜,
 reset_password_email_sent_at: 〜,
 access_count_to_reset_password_page: 〜,

id以外のname: "morikuma"を使って、検索ができました。

pry(main)> User.find_by(name: "hogehogehoge")
  User Load (0.6ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 9 LIMIT 1
=> nil

該当しない名前で処理した場合nilが返ってきます。
エラー処理の分岐などを考える際に、押さえておくとつまづかずに済むポイントです。

whereメソッド

User.where(place: "tokyo")

・「id」以外でも検索できます
・該当する複数のデータをすべて取得します
・検索に該当するものがなかった場合は空の配列を返します

pry(main)> User.where(place: "tokyo")
  User Load (0.5ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` IN (1, 2, 3, 4)
=> [#<User:0x00007f8949c24460
 id: 1,
 name:""morikuma"
 email: "〜",
 place: "tokyo"
 〜〜〜
 〜〜〜,

 id: 3,
 name:"hayashikuma"
 email: "〜",
 place: "tokyo"
 〜〜〜
 〜〜〜,

一部データの表示を省略しましたが、一つの情報で複数のデータを取得できました。

pry(main)> User.where(place: hawaii)
  User Load (0.7ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 9
=> []

検索に該当するものがなかった場合は空の配列が返ってきます。

それぞれの挙動と、falseの返り値を踏まえて適切な方法をきちんと使い分けられるようになりたいです。
whereについては、まだ使い慣れていない所がありますので誤りなどありましたら恐れ入りますがご指摘ください。

今日はこのあたりで失礼します。

参考サイト

ActiveRecordのfindとfind_byとwhereの違いとか更新とか
https://t4traw.github.io/20140409how-to-active_record-find-and-find_by-and-where.html

find、find_by、whereの違い
https://qiita.com/tsuchinoko_run/items/f3926caaec461cfa1ca3

13
10
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
10