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

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

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

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

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

Ответы [ 17 ]

6 голосов
/ 24 ноября 2011

Просто сделайте это обычным способом:

validates_presence_of :email, :message => "Email is required."

Но покажите это так

<% if @user.errors.any? %>
  <% @user.errors.messages.each do |message| %>
    <div class="message"><%= message.last.last.html_safe %></div>
  <% end %>
<% end %>

Возвращает

"Email is required."

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

Мне нравится возможность вставлять имя поля где-то, кроме начала строки:

validates_uniqueness_of :email, :message => "There is already an account with that email."
2 голосов
/ 23 июня 2011

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

object.errors.each do |attr,message|
  puts "<li>"+message+"</li>"
end
1 голос
/ 02 декабря 2016

По вашему мнению

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

Если вы хотите переопределить сообщение об ошибке без имени атрибута, просто добавьте к сообщению ^ как:

validates :last_name,
  uniqueness: {
    scope: [:first_name, :course_id, :user_id],
    case_sensitive: false,
    message: "^This student has already been registered."
  }
0 голосов
/ 22 ноября 2018

Уникальный подход, о котором я не видел никого!

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

  1. Разрешить создание сообщения проверки как обычно, вам не нужно пытаться изменить его в помощнике проверки.

  2. создает обратный вызов after_validation, который заменит это сообщение проверки в серверной части до того, как оно попадет в представление.

  3. В методе 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 будет иметь гораздо большую область действия, чем встроенный помощник проверки рельсов, поэтому вы сможете получить доступ к объекту, который вы проверяете, так же, как вы пытаетесь делать с object.file_name. Что не работает в помощнике проверки, где вы пытаетесь вызвать его.

Примечание: мы используем ^, чтобы избавиться от имени атрибута в начале проверки, поскольку @Rystraum указал на ссылку gem

0 голосов
/ 25 октября 2018

Если вы работаете с Rails-5, вы также можете перейти к следующему:

проверяет: user_name, наличие: true, уникальность: {сообщение: "имя пользователя уже существует."}

0 голосов
/ 02 августа 2017

Вот мой код, который может пригодиться вам, если он вам все еще нужен: Моя модель:

validates :director, acceptance: {message: "^Please confirm that you are a director of the company."}, on: :create, if: :is_director?

Затем я создал помощника для отображения сообщений:

module ErrorHelper
  def error_messages!
    return "" unless error_messages?
    messages = resource.errors.full_messages.map { |msg|
       if msg.present? && !msg.index("^").nil?
         content_tag(:p, msg.slice((msg.index("^")+1)..-1))
       else
         content_tag(:p, msg)
       end
    }.join

    html = <<-HTML
      <div class="general-error alert show">
        #{messages}
      </div>
    HTML

    html.html_safe
  end

  def error_messages?
    !resource.errors.empty?
  end
end
0 голосов
/ 04 декабря 2016

Я попробовал следующее, у меня сработало:)

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 %> 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...