2012-05-17 18 views
5

Aquí está mi definición de la clase actual y especificaciones:máquina de estado, Modelo validaciones y 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 

Cuando ejecuto la especificación, consigo dos fracasos y un éxito. No tengo ni idea de porqué. Para dos de los estados, la instrucción return if end_time.blank? en el método end_time_before_final se evalúa como verdadera cuando debería ser falsa cada vez. 'pospuesto' es el único estado que parece pasar. ¿Alguna idea de lo que podría estar pasando aquí?

+0

'before_transition: ON =>: game_ended' parece incompleta – apneadiving

+0

son los objetos válidos en sus especificaciones que fallan? – apneadiving

+0

Se ha eliminado la before_transition. Dos de los objetos son válidos para: end_time y uno es válido para: end_time. – keruilin

Respuesta

13

Parece que se está ejecutando en una advertencia señala en el documentation:

Una importante advertencia aquí es que, debido a una limitación en el marco de validación de ActiveModel, validadores personalizados no funcionarán como esperado cuando se define para ejecutar en múltiples estados. Por ejemplo:

class Vehicle 
    include ActiveModel::Validations 

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

En este caso, el: validación speed_is_legal sólo va a funcionar para el : Estado second_gear. Para evitar esto, puede definir su validación encargo de este modo:

class Vehicle 
    include ActiveModel::Validations 

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

¡Dulce! Paga para leer Gracias por ser más observador que yo. – keruilin

Cuestiones relacionadas