簡體   English   中英

如何為兩個字段添加 ruby​​ on rails 模型驗證?

[英]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

在上面的模型中,我需要添加以下驗證:

  1. 如果用戶選擇任何一個字段,其他字段應該為零( maximum_userslast_registration_date )。
  2. 用戶不能同時添加這兩個字段值。
  3. 用戶可以選擇不選擇任何值。 但如果他當時選擇,任何領域都必須被允許。
  4. maximum_users允許小於999
  5. 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM