使用Rails我试图得到一个错误消息,如“歌曲字段不能为空”保存。做以下事情:

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

... 只显示“Song Rep XYW不能为空”,这是不好的,因为字段的标题不是用户友好的。如何更改字段本身的标题?我可以更改数据库中字段的实际名称,但我有多个“song”字段,我确实需要特定的字段名称。

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


当前回答

在你看来

object.errors.each do |attr,msg|
  if msg.is_a? String
    if attr == :base
      content_tag :li, msg
    elsif msg[0] == "^"
      content_tag :li, msg[1..-1]
    else
      content_tag :li, "#{object.class.human_attribute_name(attr)} #{msg}"
    end
  end
end

当你想重写错误消息而不带属性名时,只需在消息前面加上^ like:

validates :last_name,
  uniqueness: {
    scope: [:first_name, :course_id, :user_id],
    case_sensitive: false,
    message: "^This student has already been registered."
  }

其他回答

我试着跟随,为我工作:)

1 job.rb

class Job < ApplicationRecord
    validates :description, presence: true
    validates :title, 
              :presence => true, 
              :length => { :minimum => 5, :message => "Must be at least 5 characters"}
end

2 jobs_controller.rb

def create
      @job = Job.create(job_params)
      if @job.valid?
        redirect_to jobs_path
      else
        render new_job_path
      end     
    end

3 _form.html.erb

<%= form_for @job do |f| %>
  <% if @job.errors.any? %>
    <h2>Errors</h2>
    <ul>
      <% @job.errors.full_messages.each do |message|%>
        <li><%= message %></li>
      <% end %>  
    </ul>
  <% end %>
  <div>
    <%= f.label :title %>
    <%= f.text_field :title %>
  </div>
  <div>
    <%= f.label :description %>
    <%= f.text_area :description, size: '60x6' %>

  </div>
  <div>
    <%= f.submit %>
  </div>
<% end %> 

关于被接受的答案和列表中的另一个答案:

我正在确认nanamkim的custom-err-msg的分支与Rails 5和区域设置一起工作。

您只需要用一个插入符号开始locale消息,它不应该在消息中显示属性名称。

模型定义为:

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

用下面的en.yml:

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

item.errors。Full_messages将显示:

You can't create an item without a name

你不能创建一个没有名称的项目

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

它可以让你做以下事情:

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

一个我从未见过任何人提到过的独特方法!

我能够获得我想要的所有定制的唯一方法是使用after_validation回调来允许我操纵错误消息。

允许正常创建验证消息,您不需要尝试在验证助手中更改它。 创建一个after_validation回调,它将在后端到达视图之前替换该验证消息。 在after_validation方法中,你可以对验证消息做任何你想做的事情,就像一个普通的字符串!您甚至可以使用动态值并将它们插入到验证消息中。


#this could be any validation
validates_presence_of :song_rep_xyz, :message => "whatever you want - who cares - we will replace you later"

after_validation :replace_validation_message

def replace_validation_message
    custom_value = #any value you would like
    errors.messages[:name_of_the_attribute] = ["^This is the replacement message where 
    you can now add your own dynamic values!!! #{custom_value}"]
end

after_validation方法的作用域将比内置的rails验证帮助器大得多,因此您将能够访问正在验证的对象,就像您尝试使用object.file_name一样。这在您试图调用它的验证助手中不起作用。

注意:我们在验证的开始使用^来去掉属性名,就像@Rystraum引用这个gem时指出的那样

试试这个。

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

我在这里找到了这个。

Rails 3到6的更新:

validate do |user|
  user.errors.add(:base, "Country can't be blank") if user.country_iso.blank?
end

这是另一种方法。 您要做的就是在模型类上定义一个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

上面的代码来自这里