Ruby-on-rails 如何在 Rails 3 中将多个属性传递给 find_or_create_by?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3997034/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I pass multiple attributes to find_or_create_by in Rails 3?
提问by AKWF
I want to use find_or_create_by, but this statement does NOT work. It does not "find" or "create" with the other attributes.
我想使用 find_or_create_by,但此语句不起作用。它不会“查找”或“创建”其他属性。
productproperty = ProductProperty.find_or_create_by_product_id(:product_id => product.id, :property_id => property.id, :value => d[descname])
There seems to be very little, or no, information on the use of dynamic finders in Rails 3. "and"-ing these together gives me a an unknown method error.
关于在 Rails 3 中使用动态查找器的信息似乎很少,或者没有。将这些“和”组合在一起给我一个未知的方法错误。
UPDATE:
更新:
Originally I couldn't get the following to work. Please assume I'm not an idiot and "product" is an instance of Product AR model.
最初我无法让以下工作正常工作。请假设我不是白痴,“产品”是产品 AR 模型的一个实例。
product.product_properties.find_or_create_by_property_id_and_value(:property_id => 1, :value => "X")
The error methods was:
错误方法是:
no such keys: property_id, value
I couldn't figure that out. Only this morning did I find the reference to passing the values like this instead:
我想不通。直到今天早上,我才找到了传递这样的值的参考:
product.product_properties.find_or_create_by_property_id_and_value(1, "X")
And voilá, it works fine. I would have expected a hash to work in the same situation but I guess not.
瞧,它工作正常。我本来希望哈希能在相同的情况下工作,但我猜不是。
So I guess you get a down vote if you miss something on the internet?
所以我想如果你错过了互联网上的某些东西,你会得到反对票吗?
回答by Lelon
If you want to search by multiple attributes, you can use "and" to append them. For example:
如果要按多个属性进行搜索,可以使用“和”来附加它们。例如:
productproperty = ProductProperty.find_or_create_by_product_id_and_property_id_and_value(:product_id => product.id, :property_id => property.id, :value => d[descname])
There is one minor catch to be aware of. It will always return the object you've specified, even if that object can't be saved due to validation errors. So make sure you check to see if the returned object has an id (or is_valid?). Don't assume its in the database.
有一个小问题需要注意。它将始终返回您指定的对象,即使该对象由于验证错误而无法保存。因此,请务必检查返回的对象是否具有 id(或 is_valid?)。不要假设它在数据库中。
Alternatively, you can use the 'bang' version of the method to raise an error if the object cannot be saved:
或者,如果无法保存对象,您可以使用该方法的“bang”版本来引发错误:
http://guides.rubyonrails.org/active_record_querying.html#find-or-create-by-bang
http://guides.rubyonrails.org/active_record_querying.html#find-or-create-by-bang
This applies to Rails 3.
这适用于 Rails 3。
回答by BvuRVKyUVlViVIc7
See http://api.rubyonrails.org/classes/ActiveRecord/Base.html:
请参阅http://api.rubyonrails.org/classes/ActiveRecord/Base.html:
With single query parameter:
使用单个查询参数:
productproperty = ProductProperty.find_or_create_by_product_id(product.id) { |u| u.property_id => property_id, u.value => d[descname] } )
or extended with multiple parameters:
或扩展多个参数:
productproperty = ProductProperty.find_or_create_by_product_id(:product_id => product.id, :property_id => property_id, :value => d[descname]) { |u| u.property_id => property_id, u.value => d[descname] } )
productproperty = ProductProperty.find_or_create_by_product_id(:product_id => product.id, :property_id => property_id, :value => d[descname]) { |u| u.property_id => property_id, u.value => d[descname] } )
Would work with:
将与:
conditions = { :product_id => product.id,
:property_id => property.id,
:value => d[descname] }
pp = ProductProperty.find(:first, :conditions => conditions) || ProductProperty.create(conditions)
回答by Pablo Cantero
You could also use where(...).first_or_create- ActiveRecord::Relation#first_or_create.
您也可以使用where(...).first_or_create- ActiveRecord::Relation#first_or_create。
product_property_attrs = { product_id: product.id,
property_id: property.id,
value: d[descname] }
product_property = ProductProperty.where(product_property_attrs).first_or_create
回答by fbelanger
In Rails 4, you can use find_or_create_by(attr1: 1, attr2: 2)to find or create by multiple attributes.
在 Rails 4 中,您可以使用find_or_create_by(attr1: 1, attr2: 2)通过多个属性来查找或创建。
You can also do something like:
您还可以执行以下操作:
User.create_with(
password: 'secret',
password_confirmation: 'secret',
confirmation_date: DateTime.now
).find_or_create_by(
email: '[email protected]',
admin: true
)
If you need to create the user with some attributes, but cannot search by those attributes.
如果您需要创建具有某些属性的用户,但无法通过这些属性进行搜索。
回答by David
I've found in Rails 3.1 you do not need to pass the attributes in as a hash. You just pass the values themselves.
我发现在 Rails 3.1 中,您不需要将属性作为哈希传递。您只需传递值本身。
ProductProperty.find_or_create_by_product_id_and_property_id_and_value(
product.id, property.id, d[descname])

