首页 > 解决方案 > 如何为两个字段添加 ruby​​ on rails 模型验证?

问题描述

#  columns
#  maximum_users           :integer(4)
#  last_registration_date  :datetime

class Training < ApplicationRecord

 validates :maximum_users, numericality: { greater_than: 0, less_than_or_equal_to: 999,  
            only_integer: true }

 validate :last_reg_date_cannot_be_in_the_past



   private
   def last_reg_date_cannot_be_in_the_past
    if last_registration_date_changed? && last_registration_date < Time.now.utc
      errors.add(:training, "can't be in the past")
    end
  end

end

在上述模型中,我需要添加以下验证:

  1. 如果用户选择任何一个字段而不是其他字段应该是 nil(maximum_userslast_registration_date)。
  2. 用户不能同时添加两个字段值。
  3. 用户可以选择不选择任何值。但如果他当时选择,任何领域都必须被允许。
  4. maximum_users允许小于999
  5. last_registration_date必须大于今天的日期。

我添加了一些验证,但不认为这是一个好习惯。

如何重构模型以涵盖上述所有场景?

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

解决方案


进行大量验证并不是一个坏习惯。在某些时候,您可能希望将其移至验证器类。

class Training < ApplicationRecord
 validates_with TrainingValidator
end

我看到的一个问题是last_registration_date可以设置maximum_users为 nil,但您maximum_users上面的验证可能不允许 nil。

app/models/concerns/traning_validator.rb

classTrainingValidator < ActiveModel::Validator 

  def validate(training)
    if training.last_registration_date_changed? && training.last_registration_date < Time.now.utc
      training.errors.add(:training, "can't be in the past")
    end

    unless training.last_registration_date.nil? || training.maximum_users.nil?
      training.errors.add(:last_registration_date, "last_registration_date cannot both be set when maximum_users is set")
    end

    unless training.maximum_users.nil? || training.maximum_users < 999
      training.errors.add(:maximum_users, "must be less than 999")
    end
  end
end

推荐阅读