rails validation of nested attributes for uniqueness when some may be marked for destroy

二次信任 提交于 2019-12-05 10:31:34
Abraham P

I've solved this as follows:

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

Thus enforcing uniqueness, and preventing a person with invalid addresses from saving, but ignoring items that are marked for destruction. If anybody has had a similiar problem and has a better/algorithmically simpler/easier to read solution, and would like to share it, that would be awesome :D

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!