Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

callbacks and validations #28

Closed
obrie opened this Issue · 4 comments

1 participant

@obrie
Owner

qoobaa opened this issue

@@@ ruby
state_machine :initial => :first do
event :boom
transition :first => :second
end

state :second
validate :something # validation fails
end

after_transition :boom, :do => lambda { puts "BOOM!!!" }
@@@

result:

@@@

object_with_state_machine.boom!
BOOM!!!
StateMachine::InvalidTransition: Cannot transition state via :boom from :first
@@@

I think it’s not expected behavior, it causes a lot of problems in my app.

original LH ticket

This ticket has 0 attachment(s).

@obrie
Owner

To me, this is expected behavior. By defining a validation for the :second state, you’re indicating that any object in that state must pass that validation. As a result, when you attempt to transition from :first to :second via :boom, the validations for :second will be run.

Can you expand on this bug?

@obrie obrie was assigned
@obrie
Owner

qoobaa commented

The problem was, that I had to check if the transition is valid or not in associated model validation. I tried to find a workaround, for instance to call a method in associated model after valid transition, but in this case it’s impossible. I’ve also tried to use after_update callback:
@@@ Ruby
state :second do
after_update { puts "BOOM!!!" }
end
@@@
... but it doesn’t work at all. Finally I use event methods with bangs to check the transition:

@@@ Ruby
class ChildModel < ActiveRecord::Base
belongs_to :parent_model
after_update { parent_model.boom! }
end
@@@

If transition fails, exception is thrown and transaction is rolled back. That’s enough for me at the moment.

@obrie
Owner

qoobaa commented

Formatting problems, once again:

The problem was, that I had to check if the transition is valid or not in associated model validation. I tried to find a workaround, for instance to call a method in associated model after valid transition, but in this case it’s impossible. I’ve also tried to use after_update callback:

@@@ ruby
state :second do
after_update { puts "BOOM!!!" }
end
@@@

... but it doesn’t work at all. Finally I use event methods with bangs to check the transition:

@@@ ruby
class ChildModel < ActiveRecord::Base
belongs_to :parent_model
after_update { parent_model.boom! }
end
@@@

If transition fails, exception is thrown and transaction is rolled back. That’s enough for me at the moment.

@obrie
Owner

If you need to do validation on the availability of an event, you can use something like:

@@@ ruby
parent_model.can_boom?
@@@

You can see all of the various instance methods that are generated for an Event in the docs. They are currently:

  • can_{name}?
  • {name}_transition
  • {name}(run_action = true)
  • {name}!(run_action = true)

Also, the latest updates on github might help you, specifically the attribute-based events: http://github.com/pluginaweek/state_machine/commit/2122d327aa835d47a71ff3bd750cfaa525e0cbb5

Feel free to re-open the ticket if you have additional feedback.

@obrie obrie closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.