【问题标题】:Rails inclusion validationRails 包含验证
【发布时间】:2012-09-30 08:03:34
【问题描述】:

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

class User < ActiveRecord::Base
  attr_accessible :language

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

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

u = User.new
u.valid?

然后我在active_model/validations/inclusion.rbinclude? 方法中得到一个TypeError: can't convert nil into String

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

validates :language, :presence => true, :inclusion => { :in => %(en fr es)}

然后验证按预期工作。如果 language 为 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(' ') 之间的区别有关。

【问题讨论】:

    标签: ruby-on-rails validation inclusion


    【解决方案1】:

    第二个条件起作用的原因是 #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 已经检查该值是否在列表中。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多