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

查看:19
本文介绍了状态机、模型验证和 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? 语句每次都应为假时计算为真.推迟"是唯一似乎通过的状态.知道这里可能发生什么吗?

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天全站免登陆