【问题标题】:Rails Accepts Nested Attributes Uniqueness ValidationsRails 接受嵌套属性唯一性验证
【发布时间】:2017-03-31 07:40:21
【问题描述】:

我有一个简单的表格,可以用来管理公司的职位。我正在使用accepts_nested_attributes API 来实现这一点。用户可以使用加号/减号按钮添加/删除位置,并为每个位置选择用户和位置。我要强制执行的一项验证是,用户不能在同一家公司拥有多个职位。我是这样执行的:

class User < ActiveRecord::Base
  has_many :positions
end

class Position < ActiveRecord::Base
  belongs_to :user
  belongs_to :company
  validates :title, presence: true
  validates :user, presence: true
  validates :company, presence: :true
  validates :user, uniqueness: { scope: :company }
end

class Company < ActiveRecord::Base
  has_many :positions
  accepts_nested_attributes_for :positions, allow_destroy: true
end

但是,我注意到如果某人被删除 - 然后重新添加到同一家公司而不在两者之间保存,则会出现错误。这是说明问题的示例:

company = Company.create(name: "Widgets")
mark = User.create(name: "Mark")
luke = User.create(name: "Luke")
mark_position = Position.create(company: company, user: mark, title: "CTO")
luke_position = Position.create(company: company, user: luke, title: "CFO")

company.positions_attributes = [
  { id: mark_position.id, _destroy: true },
  { id: john_position.id, _destroy: true },
  { user_id: mark.id, title: "CPO" },
  { user_id: john.id, title: "CMO" },
]

company.save!

验证失败:为用户将用户重复职位定位到公司

我可以做任何事情来允许这样的更改而不会导致分配验证失败(我也在数据库级别强制执行 - 这意味着这些会在服务器上引发 5xx 错误)?

【问题讨论】:

    标签: ruby-on-rails accepts-nested-attributes


    【解决方案1】:

    虽然它并不漂亮 - 您可以覆盖 positions_attributes= 以重新映射您的数据:

    def positions_attributes=(attributes)
      existing = Array(positions)
    
      attributes.each do |iteration|
        position = existing.find { |position| position.user_id.eql?(iteration[:user_id]) }
        if position
          attributes.select{ |iteration| iteration[:id].eql?(position.id) }.each{ |iteration| iteration.delete(:id) }
          iteration[:id] = position.id
        end
      end
    
      super attributes
    end
    

    【讨论】:

      猜你喜欢
      • 2022-11-15
      • 2014-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多