2012-05-17 38 views
5

这是我当前类的定义和规格:状态机模型验证和RSpec

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 

当我运行规范,我得到两个失败和成功的一个。我不知道为什么。对于其中两个州,end_time_before_final方法中的return if end_time.blank?语句每次都应该为false时会计算为true。 “推迟”是唯一似乎过去的状态。任何想法可能发生在这里?

+0

'before_transition:上=>:game_ended'似乎不完全 – apneadiving

+0

是对象发生故障的规格是否有效? – apneadiving

+0

删除了before_transition。其中两个对象适用于:end_time,另一个适用于:end_time。 – keruilin

回答

13

它看起来像你正在运行到在documentation注意到一个警告:这里

一个重要需要注意的是,由于加载ActiveModel的验证 框架的约束,自定义验证将无法正常工作预计定义为在多个状态下运行 。例如:

class Vehicle 
    include ActiveModel::Validations 

    state_machine do 
    ... 
    state :first_gear, :second_gear do 
     validate :speed_is_legal 
    end 
    end 
end 

在这种情况下,:speed_is_legal验证只会被运行 为:second_gear状态。为了避免这种情况,您可以定义 自定义验证,像这样:

class Vehicle 
    include ActiveModel::Validations 

    state_machine do 
    ... 
    state :first_gear, :second_gear do 
     validate {|vehicle| vehicle.speed_is_legal} 
    end 
    end 
end 
+0

甜蜜!支付阅读。感谢你比我更有观察力。 – keruilin