Сообщения об ошибках валидации Rails: отображение только одного сообщения об ошибке на поле - PullRequest
32 голосов
/ 03 апреля 2010

Rails отображает все сообщения об ошибках валидации, связанные с данным полем. Если у меня есть три validates_XXXXX_of :email, и я оставляю поле пустым, я получаю три сообщения в списке ошибок.

Пример:

validates_presence_of :name
validates_presence_of :email
validates_presence_of :text

validates_length_of :name, :in => 6..30
validates_length_of :email, :in => 4..40
validates_length_of :text, :in => 4..200

validates_format_of :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i<br/>

<%= error_messages_for :comment %> дает мне:

7 errors prohibited this comment from being saved

There were problems with the following fields:

Name can't be blank
Name is too short (minimum is 6 characters)
Email can't be blank
Email is too short (minimum is 4 characters)
Email is invalid
Text can't be blank
Text is too short (minimum is 4 characters)

Лучше отображать по одному сообщению за раз. Есть ли простой способ решить эту проблему? Это выглядит просто, если иметь условие типа: Если вы нашли ошибку для :email, прекратите проверку :email и перейдите к другому полю.

Ответы [ 13 ]

0 голосов
/ 08 сентября 2016
# Extracts at most <strong>one error</strong> message <strong>per field</strong> from the errors-object.
# @param  [ActiveModel::Errors] the_errors_object The errors-object.
# @raise  [ArgumentError] If the given argument is not an instance of ActiveModel::Errors.
# @return [Array] A string-array containing at most one error message per field from the given errors-object.
def get_one_error_per_field(the_errors_object)
  if the_errors_object.is_a? ActiveModel::Errors    
    errors = {}  
    the_errors_object.each do |field_name, associated_error|
      errors[field_name] = the_errors_object.full_message(field_name, associated_error) unless errors[field_name]
    end 
    return errors.values
  else
    raise ArgumentError.new('The given argument isn\'t an instance of ActiveModel::Errors!')
  end 
end 
0 голосов
/ 01 января 2016

Или вы можете просто изменить массив (с помощью метода bang delete_at), чтобы все после оставалось по умолчанию, i18n и т. Д.

<% @article.errors.keys.each { |attr| @article.errors[attr].delete_at(1) } %> 

Полный рабочий код:

<% if @article.errors.any? %>
  <% @article.errors.keys.each { |attr| @article.errors[attr].delete_at(1) } %> 
   <ul>
    <% @article.errors.full_messages.each do |msg| %>
     <li><%= msg %></li>
    <% end %>
  </ul>
<% end %>
0 голосов
/ 11 декабря 2014

Я думаю, что самый простой способ - использовать опцию allow_bank. Например, чтобы избежать отображения сообщения о том, что имя слишком короткое, когда поле оставлено пустым, вы можете сделать следующее:

validates_length_of :name, allow_blank:true, :in => 6..30
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...