2012-05-17 25 views
5

Dưới đây là định nghĩa lớp hiện tại của tôi và spec:State Machine, Model validations và 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 

Khi tôi chạy spec, tôi nhận được hai thất bại và một thành công. Tôi không biết tại sao. Đối với hai trạng thái, câu lệnh return if end_time.blank? trong phương thức end_time_before_final đánh giá là đúng khi nó sai mỗi lần. 'hoãn' là trạng thái duy nhất có vẻ như đã trôi qua. Bất kỳ ý tưởng nào về những gì có thể xảy ra ở đây?

+0

'before_transition: trên =>: game_ended' dường như không đầy đủ – apneadiving

+0

Are các đối tượng có giá trị trong thông số kỹ thuật không bạn? – apneadiving

+0

Đã xóa before_transition. Hai trong số các đối tượng hợp lệ cho: end_time và một đối tượng hợp lệ cho: end_time. – keruilin

Trả lời

13

Có vẻ như bạn đang chạy vào một caveat lưu ý trong documentation:

Một quan trọng báo trước ở đây là, do một hạn chế trong khuôn khổ xác nhận ActiveModel của, xác nhận tùy chỉnh sẽ không làm việc như dự kiến ​​khi được xác định để chạy ở nhiều trạng thái. Ví dụ:

class Vehicle 
    include ActiveModel::Validations 

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

Trong trường hợp này,: xác nhận speed_is_legal sẽ chỉ nhận được chạy cho: nhà nước second_gear. Để tránh điều này, bạn có thể xác định xác nhận tùy chỉnh của bạn như vậy:

class Vehicle 
    include ActiveModel::Validations 

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

Ngọt ngào! Trả tiền để đọc. Cảm ơn vì đã quan sát hơn tôi. – keruilin

Các vấn đề liên quan