Конечный автомат after_transition обратный вызов не работает при обновлении

#ruby-on-rails #state-machine

#ruby-on-rails #конечный автомат

Вопрос:

Я использую Rails-4.2.6 state_machine-1.2.0, и Ruby-2.3 я определил конечный автомат для модели заказа. Следующим образом

   state_machine :status, initial: :initiated do
    after_transition on: :succeeded, do: :oderable_success_callback
    event :pending do
      transition initiated: :pending
    end

    event :failed do
      transition [:initiated, :pending] => :failed
    end

    event :succeeded do
      transition [:initiated, :pending] => :succeeded
    end
  end

  def oderable_success_callback
    orderable.successful_payment
  end
  

когда я обновляю порядок следующим образом, запускается обратный вызов after_transition.

order.succeeded

но это не вызовет обратного вызова, когда я обновляю порядок как

 order.update(status: 'succeeded')
  

status обновляется до « succeeded , но не запускает обратный вызов.

Как я могу запускать after_transition обратные вызовы в обычном update режиме.

Ответ №1:

order.update не вызовет обратный вызов after_transition. Если вы хотите обнаружить изменения в столбце. Вы можете использовать обратный вызов модели after_update.

 class Order < ActiveRecord::Base
  after_update :tasks
  def tasks
    if(self.status_changed? amp;amp; status == 'succeeded')
      oderable_success_callback
    end
  end
end
  

Комментарии:

1. Спасибо за ответ. На самом деле у меня есть несколько обратных вызовов в зависимости от статуса. Если я запускаю так, тогда нужно написать много if / else.

Ответ №2:

У меня было несколько обратных вызовов в зависимости от статуса, и чтобы избежать нескольких if / else, я сделал следующее,

  after_update :orderable_callback

 state_machine :status, initial: :initiated do
    event :pending do
      transition initiated: :pending
    end

    event :failed do
      transition [:initiated, :pending] => :failed
    end

    event :succeeded do
      transition [:initiated, :pending] => :succeeded
    end

    state :pending do
      def orderable_callback
        orderable.pending_payment
      end
    end

    state :failed do
      def orderable_callback
        orderable.failed_payment
      end
    end

    state :succeeded do
      def orderable_callback
        orderable.successful_payment
      end
    end
  end
  

Комментарии:

1. Это интересно. Я не знал, что вы можете определять такие методы для каждого состояния. Но что он делает, если он находится в состоянии, которое не orderable_callback определено? (например: инициированное состояние) Не приведет ли к сбою обратный вызов after_update?

2. Вам необходимо определить метод orderable_callback вне конечного автомата, который будет вызываться по умолчанию, если он не указан в конечном автомате. Для инициированного он будет вызывать default orderable_callback