state-machines / state_machines

Adds support for creating state machines for attributes on any Ruby class
https://github.com/state-machines/state_machines
MIT License
814 stars 91 forks source link

Transition handlers are called called twice on a single event #55

Closed robert-sutton closed 7 years ago

robert-sutton commented 7 years ago

Perhaps I am missing something here, but I cannot see any real reason why the :after_transition handler in this code is called twice in this very simple example:

class StateMachineActivity 
  state_machine :state, initial: :created do
    after_transition to: :finished do |activity, transition|
      puts "Finished."
    end
    event :next do
      transition :created => :finished 
    end
  end
end

In the console, test with

>> a = StateMachineActivity.new
#<StateMachineActivity:0x00000001300150 @state="created">
>> a.next
Finished.
Finished.
true

I would expect Finished to be printed only once. Inspecting the call stack shows callbacks for the after_transition are registered TWICE, but I cannot determine why or where.

Suggestions? Ideas?

rosskevin commented 7 years ago

I don't spot a problem with your code.

I would check through the unit tests. If I recall, we have some that count executions so you might see if one exists or add a counter to one to prove your case and PR it as a start.

seuros commented 7 years ago

Thank you for providing a sample code.

I can't replicate this error.

irb(main):011:0> a = StateMachineActivity.new
=> #<StateMachineActivity:0x007f869b6a79e8 @state="created">
irb(main):012:0> a.next
Finished.
=> true

Are you using any integration ?

robert-sutton commented 7 years ago

Thanks for the quick responses guys. It appears something in the rest of the application (Rails) is interfering. A blank sample app works fine.

I will have to isolate further. Closing this issue as it appears to be my environment. I will post back when I do find the cause for the benefit of others.

thanks

rosskevin commented 7 years ago

@robert-sutton - I have long since removed callbacks in my models for indescribable behaviors. I suggest you start looking there.

robert-sutton commented 7 years ago

The cause has been discovered. The source file loaded multiple times will cause the behavior. In my case, a Rails app,

Rails.application.eager_load! (in application.rb) and require 'state_machine_activity' (explicitly included in another source file).

yields the behavior.

removing either lines of code, produces the expected behavior. Changing one of the functional tests to include Vehicle multiple times does not produce the behavior.

This seems related to Rails, though I am not sure why.