当某些属性可能被标记为销毁时,用于validation嵌套属性的唯一性

我有以下(消毒过的)模型:

class Person < ActiveRecord::Base attr_accessible :name, :first_name, :last_name, :age, :job_title, :salary, :ssn, :prison_convictions, :addresses_attributes has_many :addresses, inverse_of: :person accepts_nested_attributes_for :addresses, allow_destroy: true end class Address < ActiveRecord::Base attr_accessible :zip_code, :street,:house_number, :unique_per_person_government_id belongs_to :person, inverse_of: :addresses validates_uniqueness_of :unique_per_person_government_id, scope: :person_id end 

问题如下,

让我们说人Joe Shmoe目前有两个地址附在自己身上

666 Foo Street,12345,唯一ID:“ABCDEFG”和777 Lucky Avenue,54321,唯一ID:“GFEDCBA”

并且让我们说以下post来自一个表单:

  {:addresses_attributes => { [0] => {:unique_per_person_government_id => “ABCDEFG”, :street=> “Foo Street”, :house_number => 666, :zip_code=>12345, _destroy => 1} [1] => {:unique_per_person_government_id => “ABCDEFG”, :street=>”Bar Street”, :house_number => 888, :zip_code => 12345, _destroy => 0} } 

行为似乎是第二个(即新的)记录首先validation了唯一性,validation失败。

我想要的行为是简单地删除所有marked_for_destruction?marked_for_destruction?元素marked_for_destruction? 在进行任何进一步validation之前

如何以这种方式重新连接生命周期? 有没有更好的方法来实现这一目标?

谢谢!

我已经解决了这个问题如下:

 class Person < ActiveRecord::Base attr_accessible :name, :first_name, :last_name, :age, :job_title, :salary, :ssn, :prison_convictions, :addresses_attributes has_many :addresses, inverse_of: :person accepts_nested_attributes_for :addresses, allow_destroy: true def validate_addresses codes = {} addresses.each do |a| if codes.key?(a.unique_per_person_government_id) and not a.marked_for_destruction? codes[a.unique_per_person_government_id] = codes[a.unique_per_person_government_id]+1 if codes[a.unique_per_person_government_id] > 1 return false end elsif not codes.key?(a.unique_per_person_government_id) and a.marked_for_destruction? codes[a.code] = 0 elsif not codes.key?(a.unique_per_person_government_id) and not a.marked_for_destruction? codes[dacode] = 1 end end return true end end class Address < ActiveRecord::Base before_save :validate_addresses attr_accessible :zip_code, :street,:house_number, :unique_per_person_government_id belongs_to :person, inverse_of: :addresses validates_uniqueness_of :unique_per_person_government_id, scope: :person_id, unless: :skip_validation? def skip_validation? person.addresses.each do |a| if unique_per_person_government_id == a.code and id != a.id return false unless a.marked_for_destruction? elsif id == a.id and a.marked_for_destruction? return false end end return true end end 

因此,强制执行唯一性,并防止具有无效地址的人员保存,但忽略标记为销毁的项目。 如果有人有类似的问题,并且有更好的/算法更简单/更容易阅读的解决方案,并且想要分享它,那将是非常棒的:D