【问题标题】:ActiveRecord - validation :allow_blank is always active even if it has :unlessActiveRecord - 验证 :allow_blank 始终处于活动状态,即使它具有 :unless
【发布时间】:2014-07-03 10:38:57
【问题描述】:

我有这个模型

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)

=> 好的。没有发生错误。

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

=> 好的。发生 ActiveRecord::RecordInvalid 错误“school_name is empty”。

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

=> 好的。出现验证错误“school_grade 不是数字”。

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

=> 不合格。我预计“school_grade is not a number”错误,但没有发生错误。

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

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

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

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

谢谢。

【问题讨论】:

  • 数据库中type的数据类型是什么?

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


【解决方案1】:

allow_blank 不接受Hash,只接受布尔值,所以你不能写像:allow_blank =&gt; {:unless =&gt; :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

【讨论】:

  • 这段代码对我有用。但是我得到了validates_presence_of is deprecated in Rails,所以我就这样改了。 validates :school_grade, :presence =&gt;true, :if =&gt; :student? 谢谢。
  • 好。但现在我很好奇并担心我在 Rails 4.1.2 中的设置原因,我没有收到任何折旧警告。我搜索了一下,发现 validates_presence_of 的折旧是在 Rails 3 中。你使用的是哪个版本?
  • 在当前的 git 版本中我也看不到任何与折旧相关的代码github.com/rails/rails/blob/…
  • 我使用的是 Rails 3.2.18。感谢您的信息。它变得很有帮助。
【解决方案2】:

您希望 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?

【讨论】:

  • student?false 时,此代码不允许整数参数。我想拒绝它,但只有当student?false 时,才想允许nil。谢谢。
  • 我更新了我的答案。对 school_grade 进行两次验证。一个用于学生案例,一个用于非学生案例。
  • 最新代码运行良好。但是 Benjamin's 更简单,因为我的真实代码中还有其他验证。还是谢谢你。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-10
  • 1970-01-01
  • 1970-01-01
  • 2022-06-28
相关资源
最近更新 更多