Rails模型default_value方法与presence存在冲突

时间:2015-01-16 20:43:29

标签: ruby-on-rails rspec

我有这个简化的模型:

class Contract < ActiveRecord::Base

  belongs_to :user   belongs_to :plan

  before_validation :set_default_is_voided   
  before_validation :set_default_expiration

  validates :user, presence: true
  validates :plan, presence: true
  validates :contract_date, presence: true
  validates :is_voided, presence: true
  validates :expiration, presence: true

  protected

  def set_default_is_voided
    if self.is_voided.nil?
      self.is_voided = false
      ap self.is_voided.present?
      ap self.is_voided
    end
  end

  def set_default_expiration
    if self.contract_date.present?
      self.expiration = self.contract_date+1.month
    end
  end

end

这个rspec简化了测试:

context "Should create default values" do
  it "Have to create is_voided" do
    user = FactoryGirl.create(:user)
    plan = FactoryGirl.create(:planContract)
    ap "HERE"
    contractDefault = FactoryGirl.create(:contractDefault, plan: plan, user: user)
    ap contractDefault
    expect(contractDefault.is_voided).to eq(false)
  end
  it "Have to create expiration" do
    #expect(contract.expiration).should eq(Date.today()+1.month)
  end
end

FactoryGirl:

FactoryGirl.define do
  factory :contractVoid, class:Contract do
  end
  factory :contractDefault, class:Contract do
    contract_date Date.today
  end
end

此测试失败,'is_voided不能为空'。

问题是: 为什么before_validation中的方法“set_default_is_voided”没有通过在线真实验证?而且,self.is_voided.present?返回false,为什么会这样?

1 个答案:

答案 0 :(得分:1)

您回答了自己的问题,为什么set_default_is_voided没有通过presence: true验证,即self.is_voided.present?返回false,这就是{{} 1}}已确定。

presence: true返回self.is_voided.present?,因为falseA concise explanation of nil v. empty v. blank in Ruby on Rails

有关验证布尔字段不是false.present? == false的一种方法,请参阅Rails: how do I validate that something is a boolean?

有关nil定义背后动机的问答,请参阅http://www.quora.com/Why-does-Rails-make-false-blank-true