Использование ActiveModel :: Dirty in Rails Validations - PullRequest
0 голосов
/ 25 апреля 2018

Я пытаюсь использовать Rails ActiveModel :: Dirty в моей проверке модели, чтобы требовать наличия определенных полей в зависимости от того, что status моей записи было или будет.

ТекущийПроверки

validates :pause_reason, presence: true, if: Proc.new { |o| o.status_will_change! == "Paused" }
validates :unpause_reason, presence: true, if: Proc.new { |o| o.status_was == "Paused"  }

Таким образом, проверка pause_reason работает нормально, так как когда я меняю статус на Paused и оставляю pause_reason пустым, я получаю соответствующую ошибку "Причина приостановки не можетбыть пустым "аналогично, если я заполняю указанное поле, я не получаю ошибку.

Однако, когда я пытаюсь сохранить те же самые изменения, проверка unpause_reason также выдает ошибку" Причина отмены не может быть пустой ",Я попытался пошагово выполнить шаги в консоли rails со следующими результатами:

irb(main):026:0> o.status
=> "Open"
irb(main):027:0> o.status = "Paused"
=> "Paused"
irb(main):028:0> o.status_will_change!
=> nil ## should be "Paused" I think
irb(main):029:0> o.status_was
=> "Open"
irb(main):030:0> o.status_was == "Paused"
=> false
irb(main):031:0> o.pause_reason
=> nil
irb(main):032:0> o.valid?
=> true ## should be false 

Так что, я думаю, я немного запутался в отношении того, что происходит в процессе проверки, которая может вызвать pause_reasonпроверка (на первый взгляд) работает как задумано, но также не проходит проверку unpause_reason, когда консоль ясно показывает, что status_was равняется "Open".

Если кто-то может помочь мне понять, как использовать ActiveModel ::Грязные в Rails Validations, соответственно, будут очень благодарны.

Обновление

После дополнительных исследований я решил объединить свои «проверки статуса» в единый метод, который проверяет на update следующим образом:

validates :status_change_validations, on: :update

def status_change_validations
  if status == "Paused" && pause_reason.blank?
    errors.add(:pause_reason, 'required when pausing an order.')
  elsif status != "Paused" && status_was == "Paused" && unpause_reason.blank?
    errors.add(:unpause_reason, 'required when resuming an order.')
  elsif status == "Canceled" && cancellation_reason.blank?
    errors.add(:cancellation_reason, 'required when canceling an order.')
  elsif status != "Canceled" && status_was == "Canceled" && reopen_reason.blank?
    errors.add(:reopen_reason, 'required when reopening an order.')
  elsif status == "Reactivate" && reactivation_reason.blank?
    errors.add(:reactivation_reason, 'required when reactivating an order.')
  end
end

Это, кажется, работает именно так, как я собираюсь, хотя я все еще не уверен, почему первоначальные однострочные проверки сProcs не работают.Если кто-то все еще хотел бы объяснить это с рабочим ответом, чтобы углубить мое понимание процедур и проверок или предоставить лучший подход, чем тот, который я только что перечислил, я приму ваш ответ.Но пока это работает, поэтому я собираюсь покататься с этим.Спасибо.

...