Railsのfind、where、find_byの違い

要約

findはidを基に検索する。値がない場合、エラーを吐く

find_byはカラムを指定して検索する。値がない場合、nilを吐く

whereは条件を指定して検索する。値がない場合は#<ActiveRecord::Relation []>を吐く

find

findはidを基に検索する。値がない場合、エラーを吐く 例

irb(main):001:0> User.find(1)
  User Load (4.8ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
=> #<User id: 1, provider: "email", uid: "test@example.com", allow_password_change: false, name: "テストユーザー", nickname: nil, image: nil, email: "test-user+1@example.com", created_at: "2021-12-12 18:16:56", updated_at: "2021-12-14 08:00:35">
irb(main):002:0> User.find(9)
  User Load (0.8ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 9 LIMIT 1
Traceback (most recent call last):
        1: from (irb):2
ActiveRecord::RecordNotFound (Couldn't find User with 'id'=9)

find_by

find_byはカラムを指定して検索する。値がない場合、nilを吐く 例

irb(main):003:0> User.find_by(id:1)
  User Load (56.6ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
=> #<User id: 1, provider: "email", uid: "test@example.com", allow_password_change: false, name: "テストユーザー", nickname: nil, image: nil, email: "test-user+1@example.com", created_at: "2021-12-12 18:16:56", updated_at: "2021-12-14 08:00:35">
irb(main):004:0> User.find_by(id:2)
  User Load (2.2ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1
=> nil
irb(main):005:0> User.find_by(id:2).name
  User Load (0.8ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1
Traceback (most recent call last):
        1: from (irb):5
NoMethodError (undefined method `name' for nil:NilClass)

where

whereは条件を指定して検索する。値がない場合は空の配列#<ActiveRecord::Relation []>を吐く

irb(main):006:0> User.where(id:2)
  User Load (0.6ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 11
=> #<ActiveRecord::Relation []>
irb(main):007:0> User.where(id:1)
  User Load (0.7ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 11
=> #<ActiveRecord::Relation [#<User id: 1, provider: "email", uid: "test@example.com", allow_password_change: false, name: "テストユーザー", nickname: nil, image: nil, email: "test-user+1@example.com", created_at: "2021-12-12 18:16:56", updated_at: "2021-12-14 08:00:35">]>
irb(main):008:0> User.where(id:1).id
Traceback (most recent call last):
        1: from (irb):8
  User Load (0.7ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 11
NoMethodError (undefined method `id' for #<User::ActiveRecord_Relation:0x0000561efed5dcc0>)
Did you mean?  ids
irb(main):009:0> User.where(id:1).first
  User Load (2.7ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER BY `users`.`id` ASC LIMIT 1
=> #<User id: 1, provider: "email", uid: "test@example.com", allow_password_change: false, name: "テストユーザー", nickname: nil, image: nil, email: "test-user+1@example.com", created_at: "2021-12-12 18:16:56", updated_at: "2021-12-14 08:00:35">
irb(main):010:0> User.where(id:1).first.id
  User Load (0.7ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER BY `users`.`id` ASC LIMIT 1
=> 1