[英]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
In the above model I need to add followings validations:在上面的模型中,我需要添加以下验证:
maximum_users
or last_registration_date
).maximum_users
或last_registration_date
)。maximum_users
allowed is less than 999
. maximum_users
允许小于999
。last_registration_date
must be greater than today's date. last_registration_date
必须大于今天的日期。 I have added few validations but don't think this is a good practice.我添加了一些验证,但不认为这是一个好习惯。
How can I refactor the model to cover all the above scenarios ?如何重构模型以涵盖上述所有场景?
Having plenty of validations is not a bad practice.进行大量验证并不是一个坏习惯。 At some point you may want to move it to a validator class.
在某些时候,您可能希望将其移动到验证器类。
class Training < ApplicationRecord
validates_with TrainingValidator
end
One problem I see with what you have is that last_registration_date
can be set and maximum_users
be nil, but your maximum_users
validation above might not allow nil.我看到的一个问题是可以设置
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
I did something like this :我做了这样的事情:
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
Model :模型 :
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.