状态机,模型验证和RSpec [英] State Machine, Model Validations and RSpec

查看:128
本文介绍了状态机,模型验证和RSpec的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我当前的班级定义和规格:

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

运行规范时,我遇到了两次失败,一次成功.我不知道为什么.对于其中两个状态,end_time_before_final方法中的return if end_time.blank?语句每次均应为false时,其计算结果为true. 推迟"是唯一似乎通过的状态.您对这里可能发生的事情有任何了解吗?

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?

推荐答案

您似乎遇到了

一个重要警告是,由于ActiveModel的验证存在限制 框架,自定义验证器在定义运行时将无法按预期工作 在多个州.例如:

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

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

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

这篇关于状态机,模型验证和RSpec的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆