2012-05-17 15 views
5

Oto moja aktualna definicja klasy i specyfikacja:State, model walidacji i 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 

Kiedy biegnę spec, mam dwie porażki i jeden sukces. Nie mam pojęcia dlaczego. W przypadku dwóch stanów instrukcja return if end_time.blank? w metodzie end_time_before_final ma wartość "prawda", jeśli za każdym razem powinna być "fałsz". "przełożone" jest jedynym stanem, który wydaje się mijać. Masz pojęcie, co może się tu wydarzyć?

+0

'before_transition: na =>: game_ended' wydaje się niekompletny – apneadiving

+0

są obiekty ważne w swoich upadających widowisko? – apneadiving

+0

Usunięto before_transition. Dwa z obiektów są ważne dla: end_time i jeden jest ważny dla: end_time. – keruilin

Odpowiedz

13

Wygląda jak używasz do zastrzeżeniem zauważono w documentation:

Jeden ważne zastrzeżenie jest to, że ze względu na ograniczenia w walidacji ramach ActiveModel za niestandardowe validators nie będzie działać jako oczekiwany, gdy zostanie zdefiniowany do uruchamiania w wielu stanach. Na przykład:

class Vehicle 
    include ActiveModel::Validations 

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

W tym przypadku: speed_is_legal walidacja będzie się uruchamiać tylko dla: stan second_gear. Aby tego uniknąć, można zdefiniować walidacji niestandardową tak:

class Vehicle 
    include ActiveModel::Validations 

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

Słodko! Pays to read. Dzięki, że jesteś bardziej uważny niż ja. – keruilin