Полностью настраиваемое сообщение об ошибке валидации с Rails - PullRequest
250 голосов
/ 30 апреля 2009

Использование Rails Я пытаюсь получить сообщение об ошибке типа «Поле песни не может быть пустым» при сохранении. Делаем следующее:

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

... отображает только «Song Rep XYW не может быть пустым», что не очень хорошо, поскольку заголовок поля не является удобным для пользователя. Как я могу изменить заголовок самого поля? Я мог бы изменить фактическое имя поля в базе данных, но у меня есть несколько полей «песни», и мне нужно иметь конкретные имена полей.

Я не хочу взламывать процесс проверки рельсов, и я чувствую, что должен быть способ исправить это.

Ответы [ 17 ]

406 голосов
/ 18 мая 2010

Теперь общепринятым способом установки гуманизированных имен и пользовательских сообщений об ошибках является использование локалей .

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

Теперь гуманизированное имя и сообщение проверки присутствия для атрибута "email" были изменены.

Сообщения проверки могут быть установлены для конкретной модели + атрибут, модель, атрибут или глобально.

64 голосов
/ 05 марта 2012

В вашей модели:

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

На ваш взгляд

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

Если вы делаете вместо этого

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

вы получаете это сообщение об ошибке с именем атрибута

address1 Put some address please

если вы хотите получить сообщение об ошибке для одного атрибута

<%= @model.errors[:address1] %>
59 голосов
/ 01 мая 2009

Попробуй это.

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

Код выше здесь

18 голосов
/ 19 февраля 2011

Да, есть способ сделать это без плагина! Но это не так чисто и элегантно, как использование упомянутого плагина. Вот оно.

Если предположить, что это Rails 3 (я не знаю, отличается ли он в предыдущих версиях),

сохранить это в вашей модели:

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

и в поле зрения вместо того, чтобы оставить

@instance.errors.full_messages

как было бы, когда мы используем генератор скаффолдов, положим:

@instance.errors.first[1]

И вы получите только сообщение, указанное в модели, без имени атрибута.

Пояснение:

#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]

Пока что мы показываем только одно сообщение, всегда для первой ошибки. Если вы хотите отобразить все ошибки, вы можете зациклить хеш и показать значения.

Надеюсь, это помогло.

15 голосов
/ 18 августа 2011

Код Rails3 с полностью локализованными сообщениями:

В модели user.rb определите валидацию

validates :email, :presence => true

В config / locales / en.yml

en:  
  activerecord:
    models: 
      user: "Customer"
    attributes:
      user:
        email: "Email address"
    errors:
      models:
        user:
          attributes:
            email:
              blank: "cannot be empty"
14 голосов
/ 17 мая 2012

В пользовательском методе проверки используйте:

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

, поскольку add_to_base устарела.

errors.add_to_base("Custom error message")

12 голосов
/ 26 октября 2016

Относится к принятому ответу и другому ответу вниз по списку :

Я подтверждаю, что вилка nanamkim custom-err-msg работает с Rails 5 и с настройкой локали.

Вам просто нужно начать сообщение локали с каретки, и оно не должно отображать имя атрибута в сообщении.

Модель, определенная как:

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

вместо обычного Name You can't create an item without a name

11 голосов
/ 01 мая 2009

Я рекомендую установить custom_error_message gem (или как плагин ), первоначально написанный Дэвидом Исли

Это позволяет вам делать такие вещи, как:

validates_presence_of :non_friendly_field_name, :message => "^Friendly field name is blank"
7 голосов
/ 23 апреля 2017

Одним из решений может быть изменение формата ошибки i18n по умолчанию:

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

По умолчанию format: %{attribute} %{message}

7 голосов
/ 23 октября 2015

Вот еще один способ:

Если вы используете этот шаблон:

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

Вы можете написать свое собственное сообщение, например:

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

Таким образом, из-за подчеркивания, полное сообщение становится «Мое пользовательское сообщение», но лишний пробел в начале незаметен. Если вы действительно не хотите этого дополнительного места в начале, просто добавьте метод .lstrip.

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

Метод String.lstrip избавит от дополнительного пространства, созданного ': _', и оставит все другие сообщения об ошибках без изменений.

Или, что еще лучше, используйте в качестве ключа первое слово вашего пользовательского сообщения:

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

Теперь полное сообщение будет «Мое собственное сообщение» без лишних пробелов.

Если вы хотите, чтобы полное сообщение начиналось со слова с заглавной буквы, например «URL не может быть пустым», это невозможно сделать. Вместо этого попробуйте добавить другое слово в качестве ключа:

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

Теперь полное сообщение будет "URL не может быть пустым"

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...