为什么state_machine的事件未在模型回调中触发?

时间:2019-11-26 07:13:41

标签: ruby state-machine ruby-on-rails-6

下面是我的模型代码,用于state_machine功能的gem是'state_machines-activerecord':

class Response < ApplicationRecord
  state_machine initial: :created do

    after_transition on: :fire_answered, do: [:run_metrics]

    after_transition on: :fire_review, do: [:check_review]

    event :fire_sent do
      transition from: [:created, :sent], to: :sent
    end
    event :fire_review do
      transition from: [:sent, :answered], to: :review
    end
    event :fire_answered do
      transition from: [:sent, :review, :answered], to: :answered
    end
  end

  before_save :set_appropriate_events

  def set_appropriate_events
    self.state_event = 'fire_sent' if sent_time.present? && response_time.blank?
    self.state_event = 'fire_answered' if sent_time.present? && response_time.present?
    self.state_event = 'fire_review' if needs_review?
  end
end  

也会根据条件设置回调运行值'self.state_event',但是不会触发事件,也不会更新任何状态。

2 个答案:

答案 0 :(得分:0)

要触发事件,应使用模型实例调用该方法。 例如:model_instance.event_name

因此,就您而言,您可能必须像下面这样使用

def set_appropriate_events
    self.fire_sent if sent_time.present? && response_time.blank?
    self.fire_answered if sent_time.present? && response_time.present?
    self.fire_review if needs_review?
end

只需调用事件,它就可以正常工作

答案 1 :(得分:0)

您使用此宝石的方式错误。如果只想在保存后更新到特定状态,则直接将所需的状态值分配给实例的属性。

def set_appropriate_events
  self.state = "sent" if sent_time.present? && response_time.blank?
  self.state = "review" if sent_time.present? && response_time.present?
  self.state = "answer" if needs_review?
end

注意:以上代码不会触发gem's callbacks(如after_transition

如果您要执行特定任务并在保存后更新状态,请不要使用状态机转换,请在回调方法内调用计算机方法。

def set_appropriate_events
  if sent_time.present? && response_time.present?
    self.state = "review"
    run_metrics
  end
  ...
end