Rails包含验证

ric*_*ard 3 validation ruby-on-rails inclusion

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

class User < ActiveRecord::Base
  attr_accessible :language

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

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

u = User.new
u.valid?
Run Code Online (Sandbox Code Playgroud)

然后我得到一个TypeError: can't convert nil into Stringinclude?的方法active_model/validations/inclusion.rb.

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

validates :language, :presence => true, :inclusion => { :in => %(en fr es)}
Run Code Online (Sandbox Code Playgroud)

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

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

我甚至尝试使用proc形式:in来查看是否有任何区别,但事实并非如此.但是我真的不希望这是需要的,因为我只想在应用程序加载时生成一次列表,因为I18n.available_locales在应用程序执行期间永远不会改变.

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

class User < ActiveRecord::Base
  attr_accessible :language

  validates :language, :presence => true, :inclusion => { :in => ['en','fr','es'].join(' ') }
end
Run Code Online (Sandbox Code Playgroud)

此代码也会生成相同的错误,因此问题不在于I18n或类似的问题.它与%(en fr es)和之间的区别有关['en','fr','es'].join(' ').

rew*_*ten 11

您的第二个条件工作的原因#include?是为String类定义的:

> "qwertyuiop".include? "tyu"
true
Run Code Online (Sandbox Code Playgroud)

因此,如果您验证包含%(en fr es)(确切地说"en fr es"),则值"n f"将通过验证.

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

validates :language, :inclusion => { :in => I18n.available_locales.map(&:to_s) }
Run Code Online (Sandbox Code Playgroud)

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


Vas*_*ich 5

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