开发者

Return to previous saved state with state_machine & state_machine_audit_trail

I have a Rails 3.1 application that uses the state_machine gem (https://github.com/pluginaweek/state_machine) to track a model's states. and the state_machine-audit_trail gem (https://github.com/wvanbergen/state_machine-audit_trail) to save the state changes.

#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 :cre开发者_StackOverflowated => :rejected
  end
end

There is one particular state 'rejected' that is temporary, and I'm looking for a way to trigger an event to return the model to the previous state as saved in the WorkOrderStateTransition model (provided by the audit gem).

I created a method 'previous_state' that finds the last state transition, and when the method is called via console it does return the previous state name.

The problem is I'm unable to call that method within the state_machine transition to use it as the destination state on a restore. To illustrate, something like this does not work:

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

What I get stored as a state is a Proc.

I would have thought this would be a pretty common use case (returning to a previously saved state) but I have found very little info while searching. The only post that is relevant is Using pluginaweek's state_machine, can I reference the activerecord object during an event? But this does not use the workflow history provided by the audit gem , and also returns the state to a 'restored' state, which is not what I need.

Has anybody come across this same use case? I'm somewhat new to Ruby/Rails and I realize this may be entirely due to my lack of understanding of lambdas and variable scopes, but I've been struggling with this problem for days, and could sure use some help!

Thanks!


You are breaking what a state machine is suposed to be. It's kind of like throwing a rock into a jet turbine. Your code will become unclear at some point making it difficult to debug.

To give you a nice anecdote here is a problem that I was faced with not so long ago, mind you this is contrived and may not fit in your case

I have a User

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

Can you identify the issue at hand? What would happen if I was a User that was inactive and got suspended, how would I know where to dump the user back in to activate them? If I was a user that was active how would I return back to being active?

The solution I came up with was to remove the Suspended --> Inactive case

tl;dr think about your states and simplify them or put intermediate steps in between the crazy cases. Don't force something on a system that is not designed for that purpose

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜