ruby-on-rails - Rails 包含验证

标签 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 Stringinclude? active_model/validations/inclusion.rb的方法.

但是,如果我将验证行更改为,
validates :language, :presence => true, :inclusion => { :in => %(en fr es)}

然后验证按预期工作。如果语言为 nil 或不是您期望的列表中的条目之一,并且没有崩溃,则它是无效的。

我已经逐步完成代码以验证它是否正在生成包含列表,确实如此。那么为什么会崩溃呢?存在验证不应该解决问题并阻止任何进一步的验证吗?为什么当我生成列表而不是对值进行硬编码时它会崩溃?

我什至尝试使用 :in 的 proc 形式看看这是否有什么不同,但它没有。但是后来我真的没想到会需要它,因为我只想在应用程序加载时生成一次列表,因为 I18n.available_locales 在应用程序执行期间永远不会改变。

更新:
我有一个想法并测试了以下代码,
class User < ActiveRecord::Base
  attr_accessible :language

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

这段代码也会产生同样的错误,所以问题不在于 I18n 或类似的东西。它与 %(en fr es) 之间的差异有关和 ['en','fr','es'].join(' ') .

最佳答案

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

> "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已经检查该值是否在列表中。

关于ruby-on-rails - Rails 包含验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12659693/

相关文章:

Python - 输入验证

php - Symfony2 UniqueEntity 约束 SQL 错误而不是消息

ruby-on-rails - 哪个更适合用于 Rails 模型验证 : Proc or lambda?

c - 在运行时扫描共享对象包含

ruby-on-rails - 如何停止 rails nginx-passenger 应用程序?

ruby-on-rails - 使用 Squeel 时可以在 where block 中有条件地添加子句吗?

c++ - 逻辑 : B contained by set A 的模板和 C++ 运算符

ruby-on-rails - 在处理电子邮件回复时,我怎样才能忽略任何电子邮件客户端细节和历史记录?

ruby-on-rails - 无方法错误 :undefined method `id' for nil:NilClass