【问题标题】:Validate uniqueness of a child object in a nested form not working correctly验证嵌套形式的子对象的唯一性无法正常工作
【发布时间】:2012-03-14 16:01:55
【问题描述】:

我对 Rails 中的范围唯一性验证有疑问。如果我尝试直接在子模型中创建一个具有我不想重复的相同属性集的新对象,那么它工作正常,但是当我尝试创建一个具有两个不唯一的孩子的父对象时,验证未触发。

背景

我在 Rails 3.2 中有一个应用程序,它的视图在 HAML 中,带有 simple_form。

我有两个模型:PageProperty。一个页面可以有很多属性,并且它接受属性的嵌套属性。

我想验证一个页面不能有两个同名的属性:

#app/models/page.rb
class Page < ActiveRecord::Base
  has_many :properties
  accepts_nested_attributes_for :properties, :allow_destroy => :true
end


#app/models/property.rb
class Property < ActiveRecord::Base
  belongs_to :page
  VALID_PROPERTIES = %w(id text name xpath class css)
  validates :name, :inclusion => VALID_PROPERTIES, :uniqueness => {:scope => :page_id}
end

当然,该属性有 page_id 属性。

就像我说的,当通过它的表单创建一个新属性时,验证是有效的。如果我尝试创建一个具有相同名称和相同 page_id 的新属性,Rails 会告诉我该名称已被使用。

问题

如果我创建一个新页面,并通过嵌套表单分配各种属性,我可以绕过此验证。当 page_id 和 property_id 的组合还没有出现在数据库中时,这似乎只是一个问题,例如,如果我编辑一个 Page 模型,它已经保存了一个属性,我尝试添加一个新的同名,现在触发验证。

【问题讨论】:

    标签: ruby ruby-on-rails-3 validation


    【解决方案1】:

    我会尝试validates_associated

    class Page < ActiveRecord::Base
      has_many :properties
      accepts_nested_attributes_for :properties, :allow_destroy => :true
      validates_associated :properties 
    end
    

    更新

    关于验证状态的 Rails 指南:

    验证是通过对模型的 表,在该表中搜索具有相同值的现有记录 属性。

    您正在创建的 2 Properties 对象在数据库中尚不存在,因此无法进行唯一性验证。您应该尝试自定义验证

    class Property < ActiveRecord::Base
      #...
      validate :name, :name_uniqueness
    
      def name_uniqueness 
        self.page.properties.select {|p| p.key == self.key}.size == 1
      end
    end
    

    【讨论】:

    • @bruno077 我已经更新了我的答案,我可能已经找到了问题的另一种解释。
    • 谢谢,我通过自定义验证解决了这个问题。尽管如此,我认为这可能是一个错误,如果您具有唯一性标准验证并且您尝试创建重复条目,则模型的创建应该会失败
    • 这在将 inverse_of 添加到 Page 模型之后才起作用,而没有得到 NoMethodError: undefined method 'properties' for nil:NilClass。所以应该是has_many :properties, :inverse_of =&gt; :page。这是在 Rails 4.0.0 上
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-09
    • 2016-11-10
    • 1970-01-01
    • 1970-01-01
    • 2018-09-08
    • 2014-05-13
    • 2018-01-25
    相关资源
    最近更新 更多