3

シナリオ例: モデル Workerbelongs_toモデル Bucket。

次のクエリを参照してください。

1.9.3p194 :045 > Worker.where(bucket_id: Bucket.first).count
   (0.7ms)  SELECT COUNT(*) FROM "workers" WHERE "workers"."bucket_id" = 1
 => 38
1.9.3p194 :046 > Worker.where(bucket_id: Bucket.first.id).count
   (0.7ms)  SELECT COUNT(*) FROM "workers" WHERE "workers"."bucket_id" = 1
 => 38

1.9.3p194 :047 > Worker.new bucket_id: Bucket.first
 => #<Worker id: nil, email: nil, created_at: nil, updated_at: nil, bucket_id: nil>
1.9.3p194 :048 > Worker.new bucket_id: Bucket.first.id
 => #<Worker id: nil, email: nil, created_at: nil, updated_at: nil, bucket_id: 2>

ご覧のとおり、where関数の場合、 などのインスタンスを渡すBucket.firstと、正確な の代わりに機能しますid。したがって、関数でも機能すると思われるでしょうnew。代わりに、静かに失敗します!

なぜこのように機能するのですか?

4

3 に答える 3

3

これはActiveRecord::PredicateBuilderで発生していると思います。値がActiveRecord::Baseオブジェクトであるかどうかを確認できますid。このnewメソッドはこのコードをトリガーしないため、動作が異なります。

id私は明示的で直接渡すことを好みます。ただし、Rails 4では、次のことができるようになります。

Worker.where(bucket: Bucket.first).count

これは、初期化とうまく似ています。

Worker.new(bucket: Bucket.first)

id一般に、設定/照合する属性がで終わる場合は、を渡すことをお勧めし_idます。

更新:私も指摘したかったのですが、初期化はwhere条件を継承します。したがって、これはRails3.2で機能します。

Worker.where(bucket_id: Bucket.first).new

私はそれがPredicateBuilderを通過することになると思いますが、それについては確かではありません。これは機能しますが、お勧めしません。

于 2013-01-24T19:45:40.993 に答える
0

使用.newすると、空白のレコードが作成されますが、IDはまだありません。Active Recordでは、これはフォームに頻繁に使用されます。

.createこれは、必要な有効なパラメータが与えられた場合にIDを持つレコードを作成するということとは異なります。同様に、でレコードを選択するとBucket.first、IDを持つ既存のレコードが取得されます。

を使用する場合は.new、必要なパラメータを設定してから.save、IDを取得します。

于 2013-01-24T03:36:04.973 に答える
0

私が理解していることからBucket.first、インスタントオブジェクトを返しますがBucket.first.id、インスタントオブジェクトのIDのみを返します。

したがって、作成Worker.newして渡すbucket_id: Bucket.firstと、実際には機能しませんが、一方で、

Worker.new bucket_id: Bucket.first.id 

新しいワーカーを作成するために正しいパラメーターを渡します。

于 2013-01-24T03:20:40.997 に答える