ActiveRecord - 验证:allow_blank始终处于活动状态,即使它具有:except

时间:2014-07-03 10:38:58

标签: ruby-on-rails ruby-on-rails-3 validation activerecord

我有这个模型

class User < ActiveRecord::Base
  attr_accessible :type, :school_name, :school_grade

  validates :type, :inclusion =>{:in =>['1','2']}, :allow_blank => true
  validates :school_name,  :presence =>{:if => :student?}
  validates :school_grade, :numericality =>{:only_integer =>true}, :allow_blank => {:unless => :student?}

  def student?
    type.to_s == '1'
  end
end

我尝试了以下模式。

User.create(:type =>'2', :school_name =>nil, :school_grade =>nil)

=&GT;好。没有发生错误。

User.create(:type =>'1', :school_name =>nil, :school_grade =>1)

=&GT;好。 ActiveRecord :: RecordInvalid错误&#34; school_name为空&#34;发生。

User.create(:type =>'1', :school_name =>'foo', :school_grade =>'string is not a number')

=&GT;好。 Validetion错误&#34; school_grade不是一个数字&#34;发生。

User.create(:type =>'1', :school_name =>'foo', :school_grade =>nil)

=&GT; NG。我希望&#34; school_grade不是一个数字&#34;错误,但没有发生错误。

我也尝试了这种模式,但结果相同。

  validates :school_grade, :numericality =>{:only_integer =>true}, :allow_blank => {:if => :not_student?}

  def not_student?
    type.to_s != '1'
  end

我猜验证:allow_blank始终处于活动状态,但为什么呢?以及如何解决它?

谢谢。

2 个答案:

答案 0 :(得分:4)

allow_blank不接受Hash,只接受布尔值,因此您无法编写类似:allow_blank => {:unless => :student?}的内容,您可以在源activemodel-4.1.2 / lib / active_model中看到/validator.rb

def validate(record)
  attributes.each do |attribute|
    value = record.read_attribute_for_validation(attribute)
    next if (value.nil? && options[:allow_nil]) || (value.blank? && options[:allow_blank])
    validate_each(record, attribute, value)
  end
end

然而,您想要实现的目标可以分为两行:

class User < ActiveRecord::Base
  validates_presence_of :school_grade, :if => :student?
  validates :school_grade, :numericality =>{:only_integer =>true}, :allow_blank => true
end

答案 1 :(得分:0)

您希望allow_blank是有条件的还是整个数值验证?

如果是后者:

validates :school_grade, :numericality =>{:only_integer =>true}, :allow_blank => true, :unless => :student?
validates :school_grade, :numericality =>{:only_integer =>true}, :allow_blank => false, :if => :student?