Как я могу передать несколько атрибутов find_or_create_by в Rails 3? - PullRequest
42 голосов
/ 22 октября 2010

Я хочу использовать 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:

Первоначально я не мог заставить работать следующее. Пожалуйста, предположите, что я не идиот, а "product" является экземпляром модели Product 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")

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

Так что, я полагаю, вы получите отрицательный голос, если что-то пропустите в интернете?

Ответы [ 5 ]

52 голосов
/ 17 ноября 2010

Если вы хотите искать по нескольким атрибутам, вы можете использовать «и», чтобы добавить их. Например:

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

Есть одна незначительная добыча, о которой нужно знать. Он всегда будет возвращать указанный вами объект, даже если этот объект не может быть сохранен из-за ошибок проверки. Поэтому убедитесь, что вы проверили, есть ли у возвращенного объекта идентификатор (или is_valid?). Не включайте его в базу данных.

Кроме того, вы можете использовать версию метода «bang», чтобы вызвать ошибку, если объект не может быть сохранен:

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

Это относится к Rails 3.

23 голосов
/ 22 октября 2010

См. 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) 
10 голосов
/ 01 декабря 2013

Вы также можете использовать 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
9 голосов
/ 09 февраля 2012

Я обнаружил, что в Rails 3.1 вам не нужно передавать атрибуты в виде хэша.Вы просто передаете сами значения.

ProductProperty.find_or_create_by_product_id_and_property_id_and_value(
  product.id, property.id, d[descname])
7 голосов
/ 08 мая 2016

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...