使用state_machine&返回上一个保存状态state_machine_audit_trail

时间:2011-09-20 02:45:40

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

我有一个Rails 3.1应用程序,它使用state_machine gem(https://github.com/pluginaweek/state_machine)来跟踪模型的状态。和state_machine-audit_trail gem(https://github.com/wvanbergen/state_machine-audit_trail)来保存状态变化。

#State Machine states for Work Orders
state_machine :initial => :created do
after_transition :on=>:validate, :do=>:create_report

store_audit_trail
  event :validate do
    transition :created => :validated
  end
  event :reject do
    transition :created => :rejected
  end
end

有一个特定状态'被拒绝'是暂时的,我正在寻找一种触发事件的方法,将模型返回到保存在WorkOrderStateTransition模型中的前一状态(由审计gem提供)。

我创建了一个找到最后状态转换的方法'previous_state',当通过控制台调用该方法时,它 返回以前的状态名称。

问题是我无法在state_machine转换中调用该方法,以将其用作还原时的目标状态。为了说明,这样的事情不起作用:

  event :restore do
    transition :rejected => lambda {|wo| wo.previous_state}
  end

我作为状态存储的是Proc。

我原本以为这将是一个非常常见的用例(返回到之前保存的状态),但我在搜索时发现了很少的信息。唯一相关的帖子是Using pluginaweek's state_machine, can I reference the activerecord object during an event?但是这不会使用审计gem提供的工作流历史记录,也会将状态返回到“已恢复”状态,这不是我需要的。

是否有人遇到过同样的用例?我对Ruby / Rails有些新意,我意识到这可能完全是由于我对lambdas和变量范围缺乏了解,但我已经在这个问题上苦苦挣扎了几天,并且可以肯定会使用一些帮助!

谢谢!

1 个答案:

答案 0 :(得分:2)

你正在打破国家机器的样子。这有点像把岩石投入喷气式水轮机。您的代码在某些时候将变得不清楚,使其难以调试。

为了给你一个很好的轶事,这是我不久前遇到的一个问题,请注意,这是人为的,可能不适合你的情况

我有一个用户

  +------------+
  |            |
  v            |
Active --> Suspended --> Removed
  |           ^  |
  v           |  |
Inactive -----+  |
  ^              |
  |              |
  +--------------+

您能确定手头的问题吗?如果我是一个不活动并被暂停的用户会发生什么情况,我怎么知道将用户转回去激活它们?如果我是一个活跃的用户,我将如何返回活动状态?

我想出的解决方案是删除Suspended --> Inactive案例

tl; dr考虑你的状态并简化它们或在疯狂的情况之间加入中间步骤。不要在不是为此目的设计的系统上强制使用某些东西