为什么false会使validates_presence_of无效?

aar*_*ona 53 validation unit-testing ruby-on-rails

好的步骤来重现这个:

prompt> rails test_app
prompt> cd test_app
prompt> script/generate model event_service published:boolean
Run Code Online (Sandbox Code Playgroud)

然后进入迁移并添加not null并将default发布为false:

class CreateEventServices < ActiveRecord::Migration
  def self.up
    create_table :event_services do |t|
      t.boolean :published, :null => false, :default => false
      t.timestamps
    end
  end

  def self.down
    drop_table :event_services
  end
end
Run Code Online (Sandbox Code Playgroud)

现在迁移您的更改并运行测试:

prompt>rake db:migrate
prompt>rake
Run Code Online (Sandbox Code Playgroud)

你现在应该没有错误.现在编辑模型,以便发布validate_presence_of:

class EventService < ActiveRecord::Base
  validates_presence_of :published
end
Run Code Online (Sandbox Code Playgroud)

现在编辑单元测试event_service_test.rb:

require 'test_helper'

class EventServiceTest < ActiveSupport::TestCase
  test "the truth" do
    e = EventService.new
    e.published = false
    assert e.valid?
  end
end
Run Code Online (Sandbox Code Playgroud)

并运行rake:

prompt>rake
Run Code Online (Sandbox Code Playgroud)

您将在测试中收到错误.现在将e.published设置为true并重新运行测试.有用!我认为这可能与布尔字段有关,但我无法弄明白.这是rails中的错误吗?或者我做错了什么?

Ton*_*not 103

查看API文档 ...

如果要验证是否存在布尔字段(实际值为true和false),则需要使用validates_inclusion_of:field_name,:in => [true,false].

  • 非常丑陋的黑客...但它使它工作.谢谢! (4认同)

小智 7

validates_inclusion_of :your_field, :in => [true, false]
Run Code Online (Sandbox Code Playgroud)

当您测试只有布尔值被模型接受时,在1.3.0的shoulda匹配器之后的某些版本不再适用.

相反,你应该做这样的事情:

it { should allow_value(true).for(:your_field) }  
it { should allow_value(false).for(:your_field) }
it { should_not allow_value(nil).for(:your_field) }
Run Code Online (Sandbox Code Playgroud)

你可以在这里看到讨论.

有一个部分修复,现在警告,如果你在这里尝试这样做