データを探して取って来たい
- 「id」がわかっていて、ひとつだけ取りたい → findメソッド
- 「id」がわからないが、それ以外の情報がわかっている。ひとつだけ取りたい → find_byメソッド
- ひとつの情報で、複数のデータを取りたい → 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