Question

Using the state_machine gem, I want to have validations that run only on transitions. For example:

# Configured elsewhere:
# StateMachine::Callback.bind_to_object = true

class Walrus > ActiveRecord::Base
  state_machine :life_cycle, :initial => :fetus do
    state :fetus
    state :child
    state :adult
    state :dead

    event :coming_of_age do
      transition :child => :adult
    end


    before_transition :child => :adult do
      validate :coming_of_age_party_in_the_future
    end
  end
end

If I attach that validation to the adult state, it will fail once that date passes. But I only need it to be valid during the transition. I could add something like:

validate :coming_of_age_party_in_the_future, if: 'adult? && life_cycle_was == "child"'

but that seems to miss the point of transitions.

Also, since I am binding to the object in callbacks, how would it conditionally call 'validate', a class method? (Binding is necessary since many methods in callbacks are private.)

Was it helpful?

Solution

Have you considered using the transition if: :x feature?

It should work something like this:

event :coming_of_age do
  transition :child => :adult, if: :coming_of_age_party_in_the_future
end

You can see the section 'Class definition' in 'Example' (near the top) or 'Transition context' in 'Syntax flexibility' (pretty far down) in the README

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top