State Machine, Model Validations and RSpec
rspec, ruby, ruby-on-rails, state
Solution
It looks like you're running into a caveat noted in the documentation:
One important caveat here is that, due to a constraint in ActiveModel's validation framework, custom validators will not work as expected when defined to run in multiple states. For example:
class Vehicle
include ActiveModel::Validations
state_machine do
...
state :first_gear, :second_gear do
validate :speed_is_legal
end
end
end
In this case, the :speed_is_legal validation will only get run for the :second_gear state. To avoid this, you can define your custom validation like so:
class Vehicle
include ActiveModel::Validations
state_machine do
...
state :first_gear, :second_gear do
validate {|vehicle| vehicle.speed_is_legal}
end
end
end
Problem
Here's my current class definition and spec: ``` class Event < ActiveRecord::Base # ... state_machine :initial => :not_started do event :game_started do transition :not_started => :in_progress end event :game_ended do transition :in_progress => :final end event :game_postponed do transition [:not_started, :in_progress] => :postponed end state :not_started, :in_progress, :postponed do validate :end_time_before_final end end def end_time_before_final return if end_time.blank? errors.add :end_time, "must be nil until event is final" if end_time.present? end end describe Event do context 'not started, in progress or postponed' do describe '.end_time_before_final' do ['not_started', 'in_progress', 'postponed'].each do |state| it 'should not allow end_time to be present' do event = Event.new(state: state, end_time: Time.now.utc) event.valid? event.errors[:end_time].size.should == 1 event.errors[:end_time].should == ['must be nil until event is final'] end end end end end ``` When I run the spec, I get two failures and one success. I have no idea why. For two of the states, the `return if end_time.blank?` statement in the `end_time_before_final` method evaluates to true when it should be false each time. 'postponed' is the only state that seems to pass. Any idea as to what might be happening here?