154

私はレールが初めてです。レコードを見つける方法はたくさんあると思います:

  1. find_by_<columnname>(<columnvalue>)
  2. find(:first, :conditions => { <columnname> => <columnvalue> }
  3. where(<columnname> => <columnvalue>).first

そして、それらすべてがまったく同じ SQL を生成することになるようです。また、複数のレコードを見つける場合も同じことが当てはまると思います。

  1. find_all_by_<columnname>(<columnvalue>)
  2. find(:all, :conditions => { <columnname> => <columnvalue> }
  3. where(<columnname> => <columnvalue>)

どちらを使用するかについての経験則または推奨事項はありますか?

4

12 に答える 12

143

ここでActiveRecord::Relation を返します

次に、find_by の実装を見てみましょう。

def find_by
  where(*args).take
end

ご覧のとおり、 find_byはwhereと同じですが、1 つのレコードのみを返します。このメソッドは 1 つのレコードを取得する場合に使用し、 whereはいくつかの条件ですべてのレコードを取得する場合に使用する必要があります。

于 2014-04-03T09:49:47.277 に答える
124

編集: この回答は非常に古く、この投稿が作成されてから他のより良い回答が出てきました。詳細については、@Hossam Khamis によって以下に投稿されたものを参照することをお勧めします。

ニーズに最も適していると思われるものを使用してください。

このfindメソッドは通常、ID で行を取得するために使用されます。

Model.find(1)

find指定した属性でアイテムが見つからない場合、例外がスローされることに注意してください。where例外がスローされるのを避けるために (以下で説明するように、属性が見つからない場合は空の配列を返します) を使用します。

の他の使用法はfind、通常、次のようなものに置き換えられます。

Model.all
Model.first

find_byは、列内の情報を検索するときにヘルパーとして使用され、命名規則でそのようにマップされます。たとえばname、データベースに という名前の列がある場合、次の構文を使用します。

Model.find_by(name: "Bob")

.where従来のヘルパーが機能しない場合にもう少し複雑なロジックを使用できるようにするキャッチオールであり、条件に一致するアイテムの配列 (または空の配列) を返します。

于 2012-06-22T18:17:32.763 に答える
51

Model.find

1- パラメータ: 検索するオブジェクトの ID。

2- 見つかった場合: オブジェクトを返します (1 つのオブジェクトのみ)。

3- 見つからない場合:ActiveRecord::RecordNotFound例外が発生します。

Model.find_by

1- パラメータ: キー/値

例:

User.find_by name: 'John', email: 'john@doe.com'

2- 見つかった場合: オブジェクトを返します。

3- 見つからない場合: を返しますnil

注:上げたい場合はActiveRecord::RecordNotFound使用find_by!

Model.where

1- パラメータ: と同じfind_by

2- 見つかった場合:ActiveRecord::Relationパラメータに一致する 1 つ以上のレコードを含むものを返します。

3- 見つからない場合: Empty を返しActiveRecord::Relationます。

于 2016-12-27T00:32:15.430 に答える
34

findと の間には違いがありfind_byfind見つからない場合はエラーを返しますが、 find_bynull を返します。

find_by email: "haha"ではなく、 のようなメソッドがあると読みやすい場合があります.where(email: some_params).first

于 2012-06-22T18:20:56.463 に答える
18

Rails 4以降、次のことができます:

User.find_by(name: 'Bob')

これはfind_by_nameRails 3 と同等です。

物足りない#where時に#find使います。#find_by

于 2014-06-22T13:51:09.887 に答える
8

id受け入れられた答えは一般的にそれをすべてカバーしていますが、更新のような方法でモデルを操作することを計画していて、単一のレコード (あなたが知らない) を取得してfind_byいる場合に備えて、何かを追加したいと思います。レコードを取得し、配列に配置しないため、進むべき道

irb(main):037:0> @kit = Kit.find_by(number: "3456")
  Kit Load (0.9ms)  SELECT "kits".* FROM "kits" WHERE "kits"."number" = 
 '3456' LIMIT 1
=> #<Kit id: 1, number: "3456", created_at: "2015-05-12 06:10:56",   
updated_at: "2015-05-12 06:10:56", job_id: nil>

irb(main):038:0> @kit.update(job_id: 2)
(0.2ms)  BEGIN Kit Exists (0.4ms)  SELECT 1 AS one FROM "kits" WHERE  
("kits"."number" = '3456' AND "kits"."id" != 1) LIMIT 1 SQL (0.5ms)   
UPDATE "kits" SET "job_id" = $1, "updated_at" = $2 WHERE  "kits"."id" = 
1  [["job_id", 2], ["updated_at", Tue, 12 May 2015 07:16:58 UTC +00:00]] 
(0.6ms)  COMMIT => true

ただし、使用する場合where、直接更新することはできません

irb(main):039:0> @kit = Kit.where(number: "3456")
Kit Load (1.2ms)  SELECT "kits".* FROM "kits" WHERE "kits"."number" =  
'3456' => #<ActiveRecord::Relation [#<Kit id: 1, number: "3456", 
created_at: "2015-05-12 06:10:56", updated_at: "2015-05-12 07:16:58", 
job_id: 2>]>

irb(main):040:0> @kit.update(job_id: 3)
ArgumentError: wrong number of arguments (1 for 2)

そのような場合、このように指定する必要があります

irb(main):043:0> @kit[0].update(job_id: 3)
(0.2ms)  BEGIN Kit Exists (0.6ms)  SELECT 1 AS one FROM "kits" WHERE 
("kits"."number" = '3456' AND "kits"."id" != 1) LIMIT 1 SQL (0.6ms)   
UPDATE "kits" SET "job_id" = $1, "updated_at" = $2 WHERE "kits"."id" = 1  
[["job_id", 3], ["updated_at", Tue, 12 May 2015 07:28:04 UTC +00:00]]
(0.5ms)  COMMIT => true
于 2015-05-12T07:36:45.943 に答える
5

あなたのリストの #2 はどちらも非推奨です。それでも使えfind(params[:id])ます。

通常、where()ほとんどの状況で機能します。

ここに素晴らしい投稿があります: https://web.archive.org/web/20150206131559/http://m.onkey.org/active-record-query-interface

于 2012-06-22T18:15:21.440 に答える