Ruby-on-rails 使用 Rails 完全自定义验证错误消息

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/808547/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 21:11:58  来源:igfitidea点击:

Fully custom validation error message with Rails

ruby-on-rails

提问by marcgg

Using Rails I'm trying to get an error message like "The song field can't be empty" on save. Doing the following:

使用 Rails 我试图在保存时收到一条错误消息,如“歌曲字段不能为空”。执行以下操作:

validates_presence_of :song_rep_xyz, :message => "can't be empty"

... only displays "Song Rep XYW can't be empty", which is not good because the title of the field is not user friendly. How can I change the title of the field itself ? I could change the actual name of the field in the database, but I have multiple "song" fields and I do need to have specific field names.

...只显示“Song Rep XYW can't be empty”,这不好,因为该字段的标题对用户不友好。如何更改字段本身的标题?我可以更改数据库中字段的实际名称,但我有多个“歌曲”字段,我确实需要有特定的字段名称。

I don't want to hack around rails' validation process and I feel there should be a way of fixing that.

我不想绕过 rails 的验证过程,我觉得应该有办法解决这个问题。

回答by graywh

Now, the accepted way to set the humanized names and custom error messages is to use locales.

现在,设置人性化名称和自定义错误消息的公认方法是使用 locales

# config/locales/en.yml
en:
  activerecord:
    attributes:
      user:
        email: "E-mail address"
    errors:
      models:
        user:
          attributes:
            email:
              blank: "is required"

Now the humanized name andthe presence validation message for the "email" attribute have been changed.

现在,“email”属性的人性化名称存在验证消息已更改。

Validation messages can be set for a specific model+attribute, model, attribute, or globally.

可以为特定模型+属性、模型、属性或全局设置验证消息。

回答by Federico

In your model:

在您的模型中:

validates_presence_of :address1, message: 'Put some address please' 

In your view

在你看来

<% m.errors.each do |attr, msg|  %>
 <%= msg %>
<% end %>

If you do instead

如果你这样做

<%= attr %> <%= msg %>

you get this error message with the attribute name

您会收到带有属性名称的错误消息

address1 Put some address please

if you want to get the error message for one single attribute

如果您想获取单个属性的错误消息

<%= @model.errors[:address1] %>

回答by Maulin

Try this.

尝试这个。

class User < ActiveRecord::Base
  validate do |user|
    user.errors.add_to_base("Country can't be blank") if user.country_iso.blank?
  end
end

I found this here.

我在这里找到了这个。

Here is another way to do it. What you do is define a human_attribute_name method on the model class. The method is passed the column name as a string and returns the string to use in validation messages.

这是另一种方法。你要做的是在模型类上定义一个 human_attribute_name 方法。该方法将列名作为字符串传递并返回字符串以在验证消息中使用。

class User < ActiveRecord::Base

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

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

end

The above code is from here

上面的代码来自这里

回答by Marco Antonio

Yes, there's a way to do this without the plugin! But it is not as clean and elegant as using the mentioned plugin. Here it is.

是的,有一种方法可以在没有插件的情况下做到这一点!但它不像使用提到的插件那样干净和优雅。这里是。

Assuming it's Rails 3 (I don't know if it's different in previous versions),

假设是Rails 3(不知道之前版本有没有不同),

keep this in your model:

将此保留在您的模型中:

validates_presence_of :song_rep_xyz, :message => "can't be empty"

and in the view, instead of leaving

并且在视图中,而不是离开

@instance.errors.full_messages

as it would be when we use the scaffold generator, put:

就像我们使用脚手架生成器时一样,输入:

@instance.errors.first[1]

And you will get just the message you specified in the model, without the attribute name.

您将只获得您在模型中指定的消息,而没有属性名称。

Explanation:

解释:

#returns an hash of messages, one element foreach field error, in this particular case would be just one element in the hash:
@instance.errors  # => {:song_rep_xyz=>"can't be empty"}

#this returns the first element of the hash as an array like [:key,"value"]
@instance.errors.first # => [:song_rep_xyz, "can't be empty"]

#by doing the following, you are telling ruby to take just the second element of that array, which is the message.
@instance.errors.first[1]

So far we are just displaying only one message, always for the first error. If you wanna display all errors you can loop in the hash and show the values.

到目前为止,我们只显示一条消息,总是针对第一个错误。如果您想显示所有错误,您可以在哈希中循环并显示值。

Hope that helped.

希望有所帮助。

回答by Lukas

Rails3 Code with fully localized messages:

带有完全本地化消息的 Rails3 代码:

In the model user.rb define the validation

在模型 user.rb 中定义验证

validates :email, :presence => true

In config/locales/en.yml

在 config/locales/en.yml

en:  
  activerecord:
    models: 
      user: "Customer"
    attributes:
      user:
        email: "Email address"
    errors:
      models:
        user:
          attributes:
            email:
              blank: "cannot be empty"

回答by amit_saxena

In the custom validation method use:

在自定义验证方法中使用:

errors.add(:base, "Custom error message")

errors.add(:base, "Custom error message")

as add_to_base has been deprecated.

因为 add_to_base 已被弃用。

errors.add_to_base("Custom error message")

errors.add_to_base("Custom error message")

回答by Rystraum

Related to the accepted answerand another answer down the list:

接受的答案列表中的另一个答案相关:

I'm confirming that nanamkim's fork of custom-err-msgworks with Rails 5, and with the locale setup.

我确认nanamkim 的 custom-err-msg 分支适用于 Rails 5 和语言环境设置。

You just need to start the locale message with a caret and it shouldn't display the attribute name in the message.

您只需要用插入符号开始区域设置消息,它不应该在消息中显示属性名称。

A model defined as:

一个模型定义为:

class Item < ApplicationRecord
  validates :name, presence: true
end

with the following en.yml:

具有以下内容en.yml

en:
  activerecord:
    errors:
      models:
        item:
          attributes:
            name:
              blank: "^You can't create an item without a name."

item.errors.full_messageswill display:

item.errors.full_messages将显示:

You can't create an item without a name

instead of the usual Name You can't create an item without a name

而不是通常的 Name You can't create an item without a name

回答by Ryan Bigg

I recommend installing the custom_error_message gem(or as a plugin) originally written by David Easley

我建议安装最初由 David Easley 编写的custom_error_message gem(或作为插件

It lets you do stuff like:

它可以让你做这样的事情:

validates_presence_of :non_friendly_field_name, :message => "^Friendly field name is blank"

回答by cappie013

One solution might be to change the i18n default error format:

一种解决方案可能是更改 i18n 默认错误格式:

en:
  errors:
    format: "%{message}"

Default is format: %{attribute} %{message}

默认是 format: %{attribute} %{message}

回答by Cruz Nunez

Here is another way:

这是另一种方式:

If you use this template:

如果您使用此模板:

<% if @thing.errors.any? %>
  <ul>
    <% @thing.errors.full_messages.each do |message| %>
      <li><%= message %></li>
    <% end %>
  </ul>
<% end %>

You can write you own custom message like this:

您可以像这样编写自己的自定义消息:

class Thing < ActiveRecord::Base

  validate :custom_validation_method_with_message

  def custom_validation_method_with_message
    if some_model_attribute.blank?
      errors.add(:_, "My custom message")
    end
  end

This way, because of the underscore, the full message becomes " My custom message", but the extra space in the beginning is unnoticeable. If you really don't want that extra space at the beginning just add the .lstripmethod.

这样,因为下划线,完整的消息变成了“我的自定义消息”,但是开头的额外空间是不明显的。如果您真的不想在开始时使用额外的空间,只需添加该.lstrip方法。

<% if @thing.errors.any? %>
  <ul>
    <% @thing.errors.full_messages.each do |message| %>
      <li><%= message.lstrip %></li>
    <% end %>
  </ul>
<% end %>

The String.lstrip method will get rid of the extra space created by ':_' and will leave any other error messages unchanged.

String.lstrip 方法将删除由 ':_' 创建的额外空间,并且将保留任何其他错误消息不变。

Or even better, use the first word of your custom message as the key:

或者更好的是,使用自定义消息的第一个单词作为关键字:

  def custom_validation_method_with_message
    if some_model_attribute.blank?
      errors.add(:my, "custom message")
    end
  end

Now the full message will be "My custom message" with no extra space.

现在完整的消息将是“我的自定义消息”,没有额外的空间。

If you want the full message to start with a word capitalized like "URL can't be blank" it cannot be done. Instead try adding some other word as the key:

如果您希望完整的消息以大写的单词开头,例如“URL 不能为空”,则无法完成。而是尝试添加一些其他单词作为键:

  def custom_validation_method_with_message
    if some_model_attribute.blank?
      errors.add(:the, "URL can't be blank")
    end
  end

Now the full message will be "The URL can't be blank"

现在完整的消息将是“URL 不能为空”