一次只允许ActiveRecord模型中的多个属性中的一个存在

时间:2016-03-13 01:34:44

标签: ruby-on-rails ruby ruby-on-rails-4 rails-activerecord

我正在努力使它在任何给定时间只能填充三列中的一列。

这是我想到的一些伪代码:

class Model < ActiveRecord::Base
  validates :column_one, presence: true,
    absence: true if (:column_two.present? || :column_three.present?)
  validates :column_two, presence: true,
    absence: true if (:column_one.present? || :column_three.present?)
  validates :column_three, presence: true,
    absence: true if (:column_one.present? || :column_two.present?)
end

是否可以在模型级别执行此操作,还是只需在控制器或参数中管理它?

2 个答案:

答案 0 :(得分:2)

您可以使用unless的proc:

validates :column_one, presence: true, unless: Proc.new { |r|
  r.column_two.present? || r.column_two.present?
}
validates :column_two, presence: true, unless: Proc.new { |r|
  r.column_one.present? || r.column_three.present?
}
validates :column_three, presence: true, unless: Proc.new { |r|
  r.column_one.present? || r.column_two.present?
}

或命名函数的符号:

validates :column_one, presence: true, unless: :other_columns_present

private

def other_columns_present
  # do checks here
end

答案 1 :(得分:1)

要在没有重复代码的情况下进行单次验证,请使用自定义验证方法:

class Model < ActiveRecord::Base
  validate :there_can_be_only_one
end

def there_can_be_only_one
  if [column_one, column_two, column_three].count(&:present?) > 1
    column_with_error = column_one.present? ? :column_one : :column_two
    errors.add(column_with_error,
      "can't be present if any other column in [column_one, column_two, column_three] is also present"
  end
end