Rails 3 нестандартно отформатированные ошибки валидации? - PullRequest
3 голосов
/ 22 мая 2011

С этой моделью:

validates_presence_of :email, :message => "We need your email address"

как довольно надуманный пример.Ошибка появляется как:

Email We need your email address

Как я могу предоставить формат самостоятельно?

Я посмотрел на исходный код ActiveModel::Errors#full_messages, и он делает это:

def full_messages
  full_messages = []

  each do |attribute, messages|
    messages = Array.wrap(messages)
    next if messages.empty?

    if attribute == :base
      messages.each {|m| full_messages << m }
    else
      attr_name = attribute.to_s.gsub('.', '_').humanize
      attr_name = @base.class.human_attribute_name(attribute, :default => attr_name)
      options = { :default => "%{attribute} %{message}", :attribute => attr_name }

      messages.each do |m|
        full_messages << I18n.t(:"errors.format", options.merge(:message => m))
      end
    end
  end

  full_messages
end

Обратите внимание на строку формата :default в опциях?Итак, я попытался:

validates_presence_of :email, :message => "We need your email address", :default => "something"

Но тогда сообщение об ошибке фактически выглядит как:

Email something

Итак, я попытался включить строку интерполяции %{message}, переопределяя версию %{attribute} %{message}Rails использует по умолчанию.Это приводит к исключению:

I18n :: MissingInterpolationArgument в SubscriptionController # create

отсутствует аргумент интерполяции в "% {message}" ({: model => "Subscription",: attribute)=> "Email",: value => ""} задано

Тем не менее, если я использую строку интерполяции %{attribute}, она не выдаст ошибку, она просто выплевывает имя гуманизированного атрибута дважды.

У кого-нибудь есть опыт? Я всегда мог сначала указать имя атрибута, но довольно часто нам нужна какая-то другая строка (маркетологи всегда усложняют дело!).

Ответы [ 2 ]

6 голосов
/ 22 мая 2011

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

class User < ActiveRecord::Base
  validate :email_with_custom_message
  ...
  private

  def email_with_custom_message
    errors.add(:base, "We need your email address") if
      email.blank?
  end
end
4 голосов
/ 22 мая 2011

Использование интернационализации для этого, вероятно, является лучшим выборомВзгляните на

http://guides.rubyonrails.org/i18n.html#translations-for-active-record-models

В частности, этот раздел:

5.1.2 Интерполяция сообщений об ошибках

Переведенное название модели, переведеноимя атрибута и значение всегда доступны для интерполяции.

Так, например, вместо сообщения об ошибке по умолчанию «не может быть пустым», вы можете использовать имя атрибута следующим образом: «Пожалуйста, заполните ваш% {атрибут} "

...