ガラシのパルプンテ頼み

地方産限界エンジニアのグローバル独り言

【5分くらいでわかる】findとfind_byとwhereの使い分け大全 | Rails入門

findメソッドの概要

  • 各モデルのidを検索キーとしてデータを取得するメソッド
  • id以外の条件で検索不可
  • 戻り値は検索対象のクラスのインスタンス
  • 取得したいデータのidが特定されている場合
# 単一のIDを指定
Customer.find(1)
Customer Load (0.4ms)  SELECT "customers".* FROM "customers" WHERE "customers"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]

# 複数のIDを指定
Customer.find(1, 2, 3)
Customer Load (8.7ms)  SELECT "customers".* FROM "customers" WHERE "customers"."id" IN ($1, $2, $3)  [["id", 1], ["id", 2], ["id", 3]]

# 配列で複数のIDを指定
Customer.find([1, 2, 3])
Customer Load (3.5ms)  SELECT "customers".* FROM "customers" WHERE "customers"."id" IN ($1, $2, $3)  [["id", 1], ["id", 2], ["id", 3]]
  • エラー時の戻り値(検索対象が存在しなかった場合)は例外を返す
Customer.find(189879)
Customer Load (1.5ms)  SELECT "customers".* FROM "customers" WHERE "customers"."id" = $1 LIMIT $2  [["id", 189879], ["LIMIT", 1]]
ActiveRecord::RecordNotFound: Couldn't find Customer with 'id'=189879

find_byの概要

  • 各モデルをid以外の条件で検索するメソッド(idでも検索可能)
  • 複数の検索条件を指定可能
  • 戻り値は検索対象のクラスのインスタンス
  • 返ってくる結果は、最初にヒットした1件のみ
  • id以外のプロパティでデータを特定したい時
Customer.find_by(name: "株式会社カンパニー")
Customer Load (7.2ms)  SELECT "customers".* FROM "customers" WHERE "customers"."name" = $1 LIMIT $2  [["name", "株式会社カンパニー"], ["LIMIT", 1]]
  • エラー時の戻り値(検索対象が存在しなかった場合)はnilを返す
Customer.find_by(name: "株式会社カンパニー")
Customer Load (34.7ms)  SELECT "customers".* FROM "customers" WHERE "customers"."name" = $1 LIMIT $2  [["name", "株式会社カンパニー"], ["LIMIT", 1]]
=> nil

whereの概要

  • 各モデルをid以外の条件で検索するメソッド
  • 該当するデータ全てが返ってくる
  • 戻り値はActiveRecord::Relationオブジェクト
  • id以外のプロパティでデータを特定したい時
# 前方一致
Customer.where('address like ?', '東京都')
Customer Load (41.9ms)  SELECT "customers".* FROM "customers" WHERE (address like '東京都')

# 後方一致
Customer.where('name like ?', '株式会社%')
Customer Load (71.4ms)  SELECT "customers".* FROM "customers" WHERE (name like '株式会社%')

# 部分一致
Customer.where('name like ?', '%カンパニー%')
Customer Load (34.8ms)  SELECT "customers".* FROM "customers" WHERE (name like '%カンパニー%')

# and検索
Customer.where('name like ?', '%カンパニー%').where('address like ?', '東京都')
Customer Load (34.8ms)  SELECT "customers".* FROM "customers" WHERE (name like '%カンパニー%')
  • エラー時の戻り値(検索対象が存在しなかった場合)も要素0個のActiveRecord::Relationオブジェクト
Customer.where('name like ?', '%カンパニー%')
Customer Load (92.5ms)  SELECT "customers".* FROM "customers" WHERE (name like '%カンパニー%')
[]