Как добавить ruby при проверке модели рельсов для двух полей? - PullRequest
0 голосов
/ 03 февраля 2020
#  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_users или last_registration_date).
  2. Пользователь не может добавить оба значения полей.
  3. Пользователь может не выбирать ни одно из значений. Но если он выберет то, любое поле должно быть разрешено.
  4. maximum_users разрешено меньше 999.
  5. last_registration_date должно быть больше, чем сегодняшняя дата.

Я добавил несколько проверок, но не думаю, что это хорошая практика.

Как я могу провести рефакторинг модели, чтобы охватить весь вышеупомянутый сценарий ios?

Ответы [ 2 ]

1 голос
/ 03 февраля 2020

Наличие большого количества проверок - неплохая практика. В какой-то момент вы можете захотеть переместить его в класс валидатора.

class Training < ApplicationRecord
 validates_with TrainingValidator
end

Одна проблема, которую я вижу с тем, что у вас есть, состоит в том, что last_registration_date может быть установлено и maximum_users равно нулю, но ваш maximum_users Приведенная выше проверка может не разрешить ноль.

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
0 голосов
/ 03 февраля 2020

Я сделал что-то вроде этого:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...