2010-10-22 81 views
42

我想使用find_or_create_by,但是這個語句不起作用。它不會與其他屬性「查找」或「創建」。如何在Rails 3中將多個屬性傳遞給find_or_create_by?

productproperty = ProductProperty.find_or_create_by_product_id(:product_id => product.id, :property_id => property.id, :value => d[descname]) 

似乎有很少或沒有對使用Rails中3動態查找器「和」信息一起-ing這些給了我一個未知的方法錯誤。

UPDATE:

本來我不能讓下面的工作。請假設我不是白癡,「產品」是產品AR模型的一個實例。

product.product_properties.find_or_create_by_property_id_and_value(:property_id => 1, :value => "X") 

錯誤方法是:

no such keys: property_id, value 

我不明白這一點。只有今天早上,我發現參考傳遞這樣的值,而不是:

product.product_properties.find_or_create_by_property_id_and_value(1, "X") 

而且瞧,它工作正常。我本來會希望哈希能在相同的情況下工作,但我想不是。

所以我想你會得到一個投票,如果你錯過了互聯網上的東西?

+3

通過「安定」他們你的意思是喜歡這裏描述的:?由多個屬性的Rails find_or_create(http://stackoverflow.com/questions/3046607/rails-find-or-create-by-more-高於一個屬性)? – Matt 2010-10-22 13:15:44

+0

我試過這個,它工作正常。什麼不工作?你有錯誤嗎? 'productproperty'的價值是什麼?這裏的文檔在這裏:http://api.rubyonrails.org/classes/ActiveRecord/Base.html(基於動態屬性的發現者) – Mischa 2010-10-22 13:19:35

回答

52

如果要通過多個屬性進行搜索,可以使用「和」來追加它們。例如:

productproperty = ProductProperty.find_or_create_by_product_id_and_property_id_and_value(:product_id => product.id, :property_id => property.id, :value => d[descname]) 

有一個小問題需要注意。它將始終返回所指定的對象,即使由於驗證錯誤而無法保存該對象。所以請確保你檢查返回的對象是否有一個id(或is_valid?)。不要假設它在數據庫中。

或者,您可以使用該方法的「砰」的版本,以提高一個錯誤,如果該對象不能保存:

http://guides.rubyonrails.org/active_record_querying.html#find-or-create-by-bang

這適用到Rails 3

+2

是的這改變了Rails 4.現在你只需要'find_or_create_by'和你想要的任何參數。見http://stackoverflow.com/questions/22520274/rails-4-find-or-create-by-method-doesnt-work – 2016-03-04 00:12:54

23

http://api.rubyonrails.org/classes/ActiveRecord/Base.html

隨着單查詢參數:

productproperty = ProductProperty.find_or_create_by_product_id(product.id) { |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] }) 

會一起工作:

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

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

對不起,犯了一個錯誤,現在糾正它。 – Lichtamberg 2010-10-22 13:18:12

+0

但是這隻能通過'product_id'進行搜索,當找到/創建時會設置'property_id'和'value'。我想@AKWF想要通過所有3個值進行搜索。 – Matt 2010-10-22 13:34:21

+0

這也適用於多個參數...更新我的文章 – Lichtamberg 2010-10-22 13:50:30

9

我已經在Rails 3.1中找到,你不需要將屬性作爲散列來傳遞。你只需傳遞這些值。

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

你也可以使用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 
5

在Rails 4中,您可以使用find_or_create_by(attr1: 1, attr2: 2)來查找或創建多個屬性。

你也可以這樣做:

User.create_with(
    password: 'secret', 
    password_confirmation: 'secret', 
    confirmation_date: DateTime.now 
).find_or_create_by(
    email: '[email protected]', 
    admin: true 
) 

如果你需要創建一些屬性的用戶,但不能被這些屬性進行搜索。