本文介绍了使用pluginaweek的state_machine,我可以在事件期间引用activerecord对象吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图实现将对象转换为挂起状态的挂起事件。但我需要能够取消暂停,并返回到以前的状态。我在模型中添加了previous_state字段,但我看不到如何在事件块内部访问它。



这是我试图实现的基本逻辑:

 事件:暂停执行
owner.previous_state = self.state
过渡[:new,::旧] => :暂停
结束

事件:取消暂停执行
过渡:暂停=> owner.previous_state.to_sym
owner.previous_state = nil
end

state_machine文档不是很有帮助,我在网上找不到示例。有时候很难知道如何向谷歌描述某些东西:)

解决方案

在我看来,这不是一个完美的解决方案,但我弄清楚了如何完成我的任务:

  state_machine:initial => :new 
state:new

state:old

state:suspended
before_transition:to => :暂停,:do => :set_previous_state

state:未挂起
after_transition:to => :未挂起,:do => :restore_previous_state

事件:暂停执行
过渡任何 - :暂停=> :暂停
结束

事件:取消暂停执行
过渡:暂停=> :未挂起,:if => :previous_state_present?
结束
结束

私人

def previous_state_present?
previous_state.present?
end

def set_previous_state
self.previous_state = state
end

def restore_previous_state
if previous_state
self .state = previous_state
self.previous_state = nil
end
end





我在挂起事件中添加了before_transition回调函数,在状态被挂起之前保存状态。



我为unsuspend事件添加了after_transition回调,因此状态立即更新为先前的状态,并且之前的状态然后消灭,以防止对象的生活中的问题。



这并不完美。它可以工作,但比创建挂起和取消挂起事件作为独立方法要复杂得多。我没有走这条路,因为我希望state_machine控制所有的状态变化,并且突破这一点就消除了防止移动到/来自无效状态,回调等的保护。

I'm trying to implement a "suspend" event that transitions the object to the :suspended state. But I need to be able to "unsuspend", and return to the previous state. I added a previous_state field to the model, but I can't see how to access it inside an event block.

This is the basic logic I'm trying to implement:

event :suspend do
  owner.previous_state = self.state
  transition [:new, :old] => :suspended
end

event :unsuspend do
  transition :suspended => owner.previous_state.to_sym
  owner.previous_state = nil
end

The state_machine docs haven't been very helpful, and I can't find examples online. Sometimes it's tough to know how to describe something to google :)

解决方案

This isn't a perfect solution in my opinion, but I did figure out how to accomplish my task:

state_machine :initial => :new do
  state :new

  state :old

  state :suspended
  before_transition :to => :suspended, :do => :set_previous_state

  state :unsuspended
  after_transition :to => :unsuspended, :do => :restore_previous_state

  event :suspend do
    transition any - :suspended => :suspended
  end

  event :unsuspend do
    transition :suspended => :unsuspended, :if => :previous_state_present?
  end
end

private

def previous_state_present?
  previous_state.present?
end

def set_previous_state
  self.previous_state = state
end

def restore_previous_state
  if previous_state
    self.state = previous_state
    self.previous_state = nil
  end
end

I started by adding an "unsuspended" state to my machine. While I never want something to stay in this state, I can't dynamically tell state_machine what state I want to unsuspend to.

I added a before_transition callback to the suspend event, to save the state before it is suspended.

I added an after_transition callback to the unsuspend event, so the state is immediately updated to the previous state, and that previous state is then wiped out to prevent issues later in the object's life.

This is not perfect. It works, but it's a lot more complicated than just creating the suspend and unsuspend events as standalone methods. I didn't go that route because I want state_machine controlling all state changes, and breaking out of that removes the protections against moving to/from invalid states, callbacks, etc.

这篇关于使用pluginaweek的state_machine,我可以在事件期间引用activerecord对象吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-23 13:52