下面是我的模型代码,用于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"也是根据条件设置的,但不会触发事件,也不会更新任何状态。
若要触发事件,应使用模型实例调用该方法。 例如: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
只需调用事件,它应该可以工作
你用错了这个宝石。如果您只想在保存后更新到特定状态,则直接将所需的状态值分配给实例的属性。
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