自定义错误消息,用于有效数字的轨道

时间:2010-01-27 21:37:21

标签: ruby-on-rails validation

我想为我的字段名称添加自定义错误消息。我偶然发现了另一个SO question

所以我添加了这样的东西:

class Product < ActiveRecord::Base
  validate do |prod|
    prod.errors.add_to_base("Product price can't be blank") if prod.prod_price.blank?
  end
end

但我也想检查prod_price的数字。如果我只是添加 validate_numericality_of :prod_price并且产品价格为空,然后两个错误消息都显示(空且不是数字)。

如果产品价格不为空,我怎能只显示'不是数字'错误消息?

我试过

class Product < ActiveRecord::Base
  validate do |prod|
    prod.errors.add_to_base("Product price can't be blank") if prod.prod_price.blank?
    if !prod.prod_price.blank?
       prod.errors.add_to_base("Product price must be a number") if prod.prod_price.<whatdo i put here>
    end
  end
end

另外,如何为“不是数字”提供自定义消息。我想隐藏向用户显示我的列名。

5 个答案:

答案 0 :(得分:5)

您可以拥有自定义消息,而无需编写自己的验证方法。只需添加:message

即可

validates_presence_of :prod_price, :message => "Product price can't be blank"

如果您想在prod_price不存在时跳过数值验证,请添加:allow_nil:

validates_presence_of :prod_price, :message => "Product price can't be blank" validates_numericality_of :prod_price, :allow_nil => true

然后,当prod_price缺失时,数字检查不会运行。

编辑:

等等,您不希望错误消息中显示字段名称,是吗?我错过了。所以你毕竟需要自定义验证。

编辑#2:

好的,那么:

protected

def validate
  if prod_price.blank?
    errors.add "Product price can't be blank"
  else
    begin
      Integer(attributes_before_type_cast["prod_price"])
    rescue ArgumentError  
      errors.add "Product price must be a number"
    end
   end
end

答案 1 :(得分:5)

currently accepted answer有效,但这是使用Rails'i18n进行数据驱动的方式:

allow_blank: true添加到validates_numericality_of将解决空白问题。

然后您可以使用i18n为您自动翻译属性名称(docs here)。 对于prod_price,您只需将其添加到en.yml

en:
  activerecord:
    attributes:
      product:
        prod_price: "Product price"

现在必须是数字部分,我们可以再次使用i18n。来自the docs

  

Active Record验证错误消息也可以轻松翻译。 Active Record为您提供了几个名称空间,您可以在其中放置邮件翻译,以便为某些模型,属性和/或验证提供不同的消息和翻译。

这些名称空间here有一个方便的表格,您可以在其中看到数字 validataion的消息not_a_number

现在我们可以将其添加到en.yml

en:
  activerecord:
    errors:
      models:
        product:
          attributes:
            prod_price:
              not_a_number: "must be a number"

现在当验证失败时,它会连接两者,给你:产品价格必须是数字

答案 2 :(得分:1)

由于很多原因,除非您需要做一些不寻常的事情,否则您应该将错误消息附加到特定字段(更容易进行单元测试,以后更容易修改错误,如果您可以显示无效字段旁边的标记想要等)。我认为你想做的事情可以通过以下方式完成:

class Product < ActiveRecord::Base
  validates_numericality_of :name, :if => lambda{ |obj| obj.prod_price? }
  validates_presence_of :name
end

答案 3 :(得分:0)

我从另一个SO问题中采用了这种方法

class User < ActiveRecord::Base

  HUMANIZED_ATTRIBUTES = {
    :email => "E-mail address"
  }

  def self.human_attribute_name(attr)
    HUMANIZED_ATTRIBUTES[attr.to_sym] || super
  end

end

这样我就不必为每个字段编写自定义消息。我只是更改呈现给用户的fild名称

答案 4 :(得分:0)

if prod.prod_price.blank?
  prod.errors.add_to_base("Product price can't be blank") 
elsif prod.prod_price.match(/[^\d]/)
  prod.errors.add_to_base("Product price must be a number")
end