【发布时间】:2020-05-19 05:50:39
【问题描述】:
# 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必须大于今天的日期。
我添加了一些验证,但我认为这不是一个好的做法。
如何重构模型以涵盖上述所有场景?
【问题讨论】:
-
我建议您在 1 个自定义验证中执行此操作,因为您可以在那里验证两个字段。
-
对于上述场景,这将是一个漫长的验证过程。有没有办法缩短这些?
-
我认为唯一可以通过
validates使用的规则是第4,也许是第5。其他人必须是自定义的,所以我建议在自定义验证中完成所有操作。是的,它会很长,但更具可读性和可维护性。但也许我错了,可以通过validates -
您也许可以对每一列进行一些条件验证。就像验证存在一样,如果 ... guides.rubyonrails.org/…
-
@vikas95prasad RE:“这将是一个冗长的验证”——是的,这就是为什么我还建议使用自定义验证而不是尝试用“聪明”来内联所有这些(但令人困惑和容易出错)
if: [Proc.new(...), ...]逻辑。更具体地说,我建议定义一个custom validator class,您可以在其中将所有这些逻辑(尤其是要求 1-3)拆分为干净的方法,并单独编写/测试它们。
标签: ruby-on-rails ruby validation ruby-on-rails-4 activerecord