Порядок / приоритет проверок рельсов - PullRequest
1 голос
/ 07 июля 2019

Я пытаюсь понять порядок / приоритет, с которым Rails обрабатывает проверки правильности. Позвольте мне привести пример.

В моем классе моделей у меня есть следующие проверки и пользовательские методы проверки:

class SupportSession < ApplicationRecord

  # Check both dates are actually provided when user submits a form
  validates :start_time, presence: true
  validates :end_time, presence: true

  # Check datetime format with validates_timeliness gem: https://github.com/adzap/validates_timeliness
  validates_datetime :start_time
  validates_datetime :end_time

  # Custom method to ensure duration is within limits
  def duration_restrictions

    # Next line returns nil if uncommented so clearly no start and end dates data which should have been picked up by the first validation checks
    # raise duration_mins.inspect # Returns nil

    # Use same gem as above to calculate duration of a SupportSession
    duration_mins = TimeDifference.between(start_time, end_time).in_minutes

    if duration_mins == 0
      errors[:base] << 'A session must last longer than 1 minute'
    end

    if duration_mins > 180
      errors[:base] << 'A session must be shorter than 180 minutes (3 hours)'
    end
  end

Проблема в том, что Rails, похоже, не обрабатывает сначала проверки 'validates присутствии' или 'validates_datetime', чтобы удостовериться, что данные находятся в первую очередь для меня, чтобы работать с ними. Я просто получаю эту ошибку в строке, где я вычисляю duration_mins (потому что нет данных start_time и end_time:

undefined method `to_time' for nil:NilClass

Есть ли причина для этого, или я просто столкнулся с ошибкой? Конечно, проверки правильности должны убедиться, что присутствуют значения для start_time и end_time, или мне нужно вручную проверять значения во всех моих пользовательских методах? Это не очень СУХОЙ.

Спасибо, что заглянули.

Ответы [ 2 ]

2 голосов
/ 07 июля 2019

Rails будет запускать все проверки в указанном порядке, даже если любая проверка не пройдена.Вероятно, вам нужно проверять дату и время только при наличии значений.

Это можно сделать двумя способами:

  1. Проверить наличие значения перед проверкой,

    validates_datetime :start_time, if: -> { start_time.present? }
    validates_datetime :end_time, if: -> { end_time.present? }
    
  2. Позволяет допустимому значению нулевой или пустой строки,

    validates_datetime :start_time, allow_blank: true
    validates_datetime :end_time, allow_blank: true
    
1 голос
/ 07 июля 2019

Самый простой способ, добавить эту строку сразу после def duration_restrictions

return if ([ start_time, end_time ].find(&:blank?))

Rails всегда сначала проверяет пользовательский метод.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...