Rails包含验证

时间:2012-09-30 08:03:35

标签: ruby-on-rails validation inclusion

我正在努力进行以下包含验证,

class User < ActiveRecord::Base
  attr_accessible :language

  validates :language, :presence => true, :inclusion => { :in => I18n.available_locales.join(' ')}
end

如果我在控制台中运行它,

u = User.new
u.valid?

然后我在TypeError: can't convert nil into String的{​​{1}}方法中获得include?

但是,如果我将验证行更改为,

active_model/validations/inclusion.rb

然后验证按预期工作。如果语言是nil或者不是列表中的其中一个条目,那么它是无效的,并且没有崩溃。

我已经逐步完成了代码,以验证它是否正在生成包含列表。那为什么会崩溃?存在验证是否应该解决问题并阻止进一步验证?为什么我生成列表时会崩溃,而不是硬编码值?

我甚至尝试使用validates :language, :presence => true, :inclusion => { :in => %(en fr es)} 的proc形式来看看它是否有所不同,但它没有。但后来我真的不希望这是需要的,因为我只想在应用程序加载时生成一次列表,因为I18n.available_locales在执行应用程序时永远不会改变。

更新: 我有一个想法,并测试了以下代码,

:in

此代码也会生成相同的错误,因此问题不在于I18n或类似的问题。这与class User < ActiveRecord::Base attr_accessible :language validates :language, :presence => true, :inclusion => { :in => ['en','fr','es'].join(' ') } end %(en fr es)之间的区别有关。

2 个答案:

答案 0 :(得分:11)

第二个条件有效的原因是为String类定义了#include?

> "qwertyuiop".include? "tyu"
true

因此,如果您在%(en fr es)中确认包含(确切为"en fr es"),则值"n f"将通过验证。

您必须使用数组(文字[]或字%w())。如果你想使用I18n.available_locales,请务必将它们转换为字符串

validates :language, :inclusion => { :in => I18n.available_locales.map(&:to_s) }

我无法重现您的错误,但:presence验证无效,因为:inclusion已经检查了列表中的值。

答案 1 :(得分:4)

您应该将数组传递给inclusion验证,而不是字符串。因此,在%(en fr es)的示例中,如果使用%w(en fr es),则可以正常使用。