示例方案:
模型工作者belongs_to模型桶。

请参阅以下查询:

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函数也适用。相反,它会无声地失败!

为什么这样工作?

最佳答案

我相信ActiveRecord::PredicateBuilder中会发生这种情况。您可以在那里看到该值是否为ActiveRecord :: Base对象,它将在其上调用idnew方法不会触发此代码,因此其行为会有所不同。

我更喜欢露骨并直接传递id。但是,upcoming in Rails 4您将能够执行以下操作:

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


与初始化非常相似:

Worker.new(bucket: Bucket.first)


通常,如果您要设置/匹配的属性以id结尾,我建议传递一个_id

更新:我还想指出,初始化将继承where条件。因此,这将在Rails 3.2中起作用:

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


我假设最终要通过PredicateBuilder,但是不确定。即使此方法有效,我也不推荐这样做。

关于ruby-on-rails-3 - 何时在Ruby on Rails ActiveRecord中传递实例来代替ID?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14493285/

10-10 17:22
查看更多