Я пытаюсь использовать 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
не работают.Если кто-то все еще хотел бы объяснить это с рабочим ответом, чтобы углубить мое понимание процедур и проверок или предоставить лучший подход, чем тот, который я только что перечислил, я приму ваш ответ.Но пока это работает, поэтому я собираюсь покататься с этим.Спасибо.