[英]How to add ruby on rails model validation for two fields?
# 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
在上面的模型中,我需要添加以下驗證:
maximum_users
或last_registration_date
)。maximum_users
允許小於999
。last_registration_date
必須大於今天的日期。我添加了一些驗證,但不認為這是一個好習慣。
如何重構模型以涵蓋上述所有場景?
進行大量驗證並不是一個壞習慣。 在某些時候,您可能希望將其移動到驗證器類。
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
我做了這樣的事情:
class NotInPastValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
record.errors.add attribute, (options[:message] || "Date can't be in the past") if value <= Time.now.utc
end
end
模型 :
validates :maximum_users,
numericality: {
greater_than: 0,
less_than_or_equal_to: 999,
only_integer: true
}
validates :last_registration_date, not_in_past: true
validate :validate_max_users_and_last_reg_date
def validate_max_users_and_last_reg_date
if maximum_users_changed? && last_registration_date_changed?
errors.add(:training, 'Specify either maximum users or last registration date, not both')
end
end
def maximum_users_changed?
changes.keys.include? 'maximum_users'
end
def last_registration_date_changed?
changes.keys.include? 'last_registration_date'
end
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.