ruby-on-rails - 如何为两个字段添加 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
在上述模型中,我需要添加以下验证:
- 如果用户选择任何一个字段而不是其他字段应该是 nil(
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
推荐阅读
- filesystems - 硬盘坏了
- java - Spring Boot Security & Vaadin 页面导航&渲染问题
- python-3.x - 如果字符串出现在数据框中,则增加一列
- c# - 创建没有外键的导航属性
- sql - SQL Server 不会将触发器事务回滚到保存点
- vue.js - 在 Vue-CLI 项目中,Babel 没有为 IE11 转换块供应商
- ios - 使用 Siesta 框架存储凭据 - iOS
- synchronization - 障碍似乎只在一个时间窗口内同步
- flutter - 颤振:没有可用的设备
- objective-c - -[NSString longLongValue] 在 0x 之后忽略我的字符串