验证范围中嵌套关联的唯一性

时间:2015-10-07 07:04:32

标签: ruby-on-rails postgresql simple-form cocoon-gem

Rails 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的唯一性。但我不喜欢验证在控制器动作中发生的想法。

1 个答案:

答案 0 :(得分:0)

Configurator上添加validates_associated可能有所帮助,但我会向Nesting添加唯一性约束。在迁移中:

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

另见:

Rails 3: Uniqueness validation for nested fields_for

Rails - Validate Nested Attributes Uniqueness with scope parent of parent

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