10
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

find_byとfindの違い

Posted at

両者の何がどう違うのか曖昧だったので、忘備録として残します。

findメソッド

主キー(ID)を使用して、特定のオブジェクトを検索する際に使用するメソッド。

↓例えば、Spree::Taxonモデルの中からid=1のオブジェクトを検索したい時

find_method_example.rb
 pry(main)> test = Spree::Taxon.find(1)
  Spree::Taxon Load (0.4ms)  SELECT  `spree_taxons`.* FROM `spree_taxons` WHERE `spree_taxons`.`id` = 1 LIMIT 1
=> #<Spree::Taxon:0x00007fbaa17a7d68
 id: 1,
 parent_id: nil,
 position: 0,
 (中略)
 meta_keywords: nil,
 depth: 0>

↓同時に複数のレコードを検索をすることも可能です。

find_method_example2.rb
pry(main)> test = Spree::Taxon.find(1,2) もしくは find([1,2])
  Spree::Taxon Load (0.4ms)  SELECT `spree_taxons`.* FROM `spree_taxons` WHERE `spree_taxons`.`id` IN (1, 2)
=> [#<Spree::Taxon:0x00007fbaa17c6358
  id: 1,
  parent_id: nil,
  (中略)
  meta_keywords: nil,
  depth: 0>,

 #<Spree::Taxon:0x00007fbaa17c6218
  id: 2,
  parent_id: nil,
  (中略)
  meta_keywords: nil,
  depth: 0>]

↓マッチするレコードが見当たらない場合、例外が発生します。
この例では9999というidは存在しないのでActiveRecord::RecordNotFoundが発生します。

find_method_example3.rb
pry(main)> test3 = Spree::Taxon.find(1,2,9999)
Spree::Taxon Load (0.5ms)  SELECT `spree_taxons`.* FROM `spree_taxons` WHERE `spree_taxons`.`id` IN (1, 2, 9999)
ActiveRecord::RecordNotFound: Couldn't find all Spree::Taxons with 'id': (1, 2, 9999) (found 2 results, but was looking for 3).

find_byメソッド

検索したい条件に合うレコードから最初に一致した1件だけを拾ってきます。

↓例えば、Spree::Productモデルの中から、promotionable: trueの条件に当てはまるオブジェクトを探す時。

find_by_method_example.rb
pry(main)> test = Spree::Product.find_by(promotionable: true)
Spree::Product Load (0.4ms)  SELECT  `spree_products`.* FROM `spree_products` WHERE `spree_products`.`deleted_at` IS NULL AND `spree_products`.`promotionable` = TRUE LIMIT 1
=> #<Spree::Product:0x00007fbaa4008398
 id: 1,
 name: "Ruby on Rails Tote",
 (中略)
 promotionable: true,
 meta_title: nil>

↓マッチするレコードが見当たらない場合、nilが返ってきます。

find_by_method_example2.rb
pry(main)> test = Spree::Product.find_by(promotionable: false)
Spree::Product Load (0.4ms)  SELECT  `spree_products`.* FROM `spree_products` WHERE `spree_products`.`deleted_at` IS NULL AND `spree_products`.`promotionable` = FALSE LIMIT 1
=> nil

↓マッチするレコードが見当たらない場合で、例外を発生させたい時find_by!で検索

find_by_method_example3.rb
pry(main)> test = Spree::Product.find_by!(promotionable: false)
  Spree::Product Load (0.4ms)  SELECT  `spree_products`.* FROM `spree_products` WHERE `spree_products`.`deleted_at` IS NULL AND `spree_products`.`promotionable` = FALSE LIMIT 1
ActiveRecord::RecordNotFound: Couldn't find Spree::Product

使用区別

IDがわかっている場合は、findメソッド
IDが不明で、別の条件でレコード検索をしたい場合は、find_byメソッド


参考

RAILS GUIDES

10
7
0

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
10
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?