Проверка уникальности вложенной ассоциации в области видимости

Рельсы 4.2, PostgreSQL 9.3

Модельные отношения:

class Nesting < ActiveRecord::Base
  belongs_to :product
  belongs_to :configurator, touch: true

  validates :product_id, uniqueness: { scope: :configurator }
end

class Configurator < ActiveRecord::Base
  has_many   :nestings, dependent: :destroy
  has_many   :products, through: :nestings

  accepts_nested_attributes_for :nestings, reject_if: :all_blank, allow_destroy: true
end

Ситуация, когда я создаю конфигуратор с продуктом foo, а затем пытаюсь обновить его, чтобы добавить продукт foo, работает нормально. Я получаю ошибку has_already_taken.

Но когда я добавляю сразу два одинаковых продукта, проверки не работают. Как проверить уникальность product_id в модели Nesting в рамках Configurator?

Мои взгляды довольно просты:

= simple_form_for @configurator, remote: true do |f|
  = f.simple_fields_for :nestings do |nesting|
    = render 'nesting_fields', f: nesting
  = link_to_add_association 'add product', f, :nestings, class: 'btn btn-default'
  = f.button :submit

_nesting_fields.html.slim

.nested-fields
  .form-inline
    = f.association :product, collection: @products
    = link_to_remove_association f, class: 'btn btn-default' do
      .glyphicon.glyphicon-remove

Одним из быстрых решений является проверка уникальности product_id's в параметрах в действиях контроллеров. Но мне не нравится идея, что проверка происходит в действии контроллера.


person mef_    schedule 07.10.2015    source источник


Ответы (1)


Добавление validates_associated на Configurator может помочь, но Я бы добавил ограничение уникальности к Nesting. В миграции:

class AddUniqueIndexToNesting < ActiveRecord::Migration
  def change
    add_index :nestings, [:configurator_id, :product_id], unique: true
  end
end

Также см:

Rails 3: Проверка уникальности для вложенных полей_для

Rails - Проверка уникальности вложенных атрибутов с родительской областью родительского < /а>

https://github.com/rails/rails/issues/1572

person thebenedict    schedule 07.10.2015
comment
Также я очеловечил сообщение об ошибке, как в модели Nesting. Я добавил метод save, вызов super и rescue ActiveRecord::RecordNotUnique - person mef_; 08.10.2015