Как передать несколько атрибутов 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. "И" -это их вместе дает мне неизвестную ошибку метода.
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")
И все это прекрасно работает. Я бы ожидал, что хеш будет работать в одной и той же ситуации, но я думаю, что нет.
Итак, я думаю, вы получаете пониженное голосование, если вы пропустите что-то в Интернете?
Ответы
Ответ 1
Если вы хотите выполнить поиск по нескольким атрибутам, вы можете использовать "и", чтобы добавить их. Например:
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?). Не принимайте его в базе данных.
В качестве альтернативы вы можете использовать версию метода "bang" для повышения ошибки, если объект не может быть сохранен:
http://guides.rubyonrails.org/active_record_querying.html#find-or-create-by-bang
Это относится к Rails 3.
Ответ 2
См. 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] } )
Забастовкa >
Работает с:
conditions = { :product_id => product.id,
:property_id => property.id,
:value => d[descname] }
pp = ProductProperty.find(:first, :conditions => conditions) || ProductProperty.create(conditions)
Ответ 3
Вы также можете использовать 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
Ответ 4
Я нашел в Rails 3.1 вам не нужно передавать атрибуты в виде хэша. Вы просто передаете сами значения.
ProductProperty.find_or_create_by_product_id_and_property_id_and_value(
product.id, property.id, d[descname])
Ответ 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
)
Если вам нужно создать пользователя с некоторыми атрибутами, но не можете выполнить поиск по этим атрибутам.