我有一个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和变量范围缺乏了解,但我已经在这个问题上苦苦挣扎了几天,并且可以肯定会使用一些帮助!
谢谢!
答案 0 :(得分:2)
你正在打破国家机器的样子。这有点像把岩石投入喷气式水轮机。您的代码在某些时候将变得不清楚,使其难以调试。
为了给你一个很好的轶事,这是我不久前遇到的一个问题,请注意,这是人为的,可能不适合你的情况
我有一个用户
+------------+
| |
v |
Active --> Suspended --> Removed
| ^ |
v | |
Inactive -----+ |
^ |
| |
+--------------+
您能确定手头的问题吗?如果我是一个不活动并被暂停的用户会发生什么情况,我怎么知道将用户转回去激活它们?如果我是一个活跃的用户,我将如何返回活动状态?
我想出的解决方案是删除Suspended --> Inactive
案例
tl; dr考虑你的状态并简化它们或在疯狂的情况之间加入中间步骤。不要在不是为此目的设计的系统上强制使用某些东西