Подтвердить что ты не робот

Как передать несколько атрибутов 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")

И все это прекрасно работает. Я бы ожидал, что хеш будет работать в одной и той же ситуации, но я думаю, что нет.

Итак, я думаю, вы получаете пониженное голосование, если вы пропустите что-то в Интернете?

4b9b3361

Ответ 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
)

Если вам нужно создать пользователя с некоторыми атрибутами, но не можете выполнить поиск по этим атрибутам.