find と find_by の違い
ActiveRecord::FinderMethods より
モノが違うので一言では書けないです
概要
#find(*arg)
- 正常系処理
- 実引数の値はテーブルのプライマリーキーに対応していることを期待
- 甲. find(value)
- 値を WHERE 句で条件制約して SELECT する
値がテーブル中に存在することを期待
- 値を WHERE 句で条件制約して SELECT する
- 乙. find([value, value, ..., value])
- 配列中の値を IN 句で条件制約して SELECT する
すべての値がテーブルに存在することを期待
- 配列中の値を IN 句で条件制約して SELECT する
- 甲. find(value)
- 実引数の値はテーブルのプライマリーキーに対応していることを期待
- 異常系処理
- 実引数の値はテーブルのプライマリーキーに対応していることを期待
- 甲. find(value)
- value に該当するプライマリーキー無し
- 乙. find([value, value, ..., value])
- value に該当するプライマリーキーが 1 つもない
- 丙. find(value)
- value が nil
- 甲. find(value)
- 異常動作
- 甲乙丙 全て ActiveRecord::RecordNotFound を raise する
- 実引数の値はテーブルのプライマリーキーに対応していることを期待
#find_by(*arg)
- 正常系処理
- 実引数の値
- 甲. fubd(field > value)
- field に対応する値を WHERE 句で条件制約して SELECT する
- 乙. find(field > array[value, value, ... value])
- field に対応する配列中の値を IN 句で条件制約して SELECT する
- 一番最初に見つかった relation を return する
- 甲. fubd(field > value)
- 実引数の値
- 異常系処理
- 実引数の値
- 甲. find(field > value)
- テーブルの field には value が存在しない
- 乙. find(field > array[value, value, ... value])
- 同上
- 甲. find(field > value)
- 異常動作
- 甲乙 共に nil が返る
- 実引数の値
詳細ベタ貼り
説明用の前提環境
- Rails 4.2.1
- Ruby 2.2.1
- MacOSX 10.10.4
- sqlite3
- マスターテーブル
- users(id @ int & PK, name @ text)
1, 'taro'
2, 'jiro'
3, 'saburo'
正常動作
甲. find(value)
> User.find(1) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
乙. find([value, value, ..., value])
> User.find([1, 2, 3]) SELECT "users".* FROM "users" WHERE "users"."id" IN (1, 2, 3)
異常動作
甲. find(value) > value に該当するプライマリーキー無し
> User.find(-1) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", -1]] ActiveRecord::RecordNotFound: Couldn't find User with 'id'=-1
乙. find([value, value, ..., value]) > value に該当するプライマリーキーが 1 つもない
> User.find([1, 2, -1]) SELECT "users".* FROM "users" WHERE "users"."id" IN (1, 2, -1) ActiveRecord::RecordNotFound: Couldn't find all Users with 'id': (1, 2, -1) (found 2 results, but was looking for 3)
丙. find(value) > value が nil
> User.find ActiveRecord::RecordNotFound: Couldn't find User without an ID
#find_by
正常動作
甲. find(field > value)
> User.find_by(name: 'taro') SELECT "users".* FROM "users" WHERE "users"."name" = ? LIMIT 1 [["name", "taro"]]
乙. find(field > array[value, value, ... value])
> User.find_by(name: ['matsukawa', 'test', 'taro']) SELECT "users".* FROM "users" WHERE "users"."name" IN ('matsukawa', 'test', 'taro') LIMIT 1 => #<User id: 1, name: "taro", created_at: "2015-08-07 16:32:24", updated_at: "2015-08-07 16:32:24">
異常動作
甲. find(field > value)
User.find_by(name: 'matsukawa') SELECT "users".* FROM "users" WHERE "users"."name" = ? LIMIT 1 [["name", "matsukawa"]] => nil
乙. find(field > array[value, value, ... value])
User.find_by(name: ['matsukawa', 'test']) SELECT "users".* FROM "users" WHERE "users"."name" IN ('matsukawa', 'test') LIMIT 1 => nil