简体   繁体   English

如何在Rails 3中将多个属性传递给find_or_create_by?

[英]How can I pass multiple attributes to find_or_create_by in Rails 3?

I want to use find_or_create_by, but this statement does NOT work. 我想使用find_or_create_by,但是这个语句不起作用。 It does not "find" or "create" with the other attributes. 它不与其他属性“查找”或“创建”。

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? 如果你错过互联网上的某些内容,我想你会得到一次投票?

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?). 因此,请确保检查返回的对象是否具有id(或is_valid?)。 Don't assume its in the database. 不要假设它在数据库中。

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。

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] } )
 
  

Would work with: 适用于:

conditions = { :product_id => product.id, 
               :property_id => property.id,
               :value => d[descname] }

pp = ProductProperty.find(:first, :conditions => conditions) || ProductProperty.create(conditions) 

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

I've found in Rails 3.1 you do not need to pass the attributes in as a hash. 我在Rails 3.1中发现你不需要将属性作为哈希传递。 You just pass the values themselves. 您只需传递值。

ProductProperty.find_or_create_by_product_id_and_property_id_and_value(
  product.id, property.id, d[descname])

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: 'admin@domain.com',
  admin: true
)

If you need to create the user with some attributes, but cannot search by those attributes. 如果需要创建具有某些属性的用户,但无法按这些属性进行搜索。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM