пользовательское сообщение об ошибке для правильного количества в рельсах - PullRequest
8 голосов
/ 28 января 2010

Я хотел иметь собственные сообщения об ошибках для имен моих полей. Я наткнулся на еще один SO вопрос

Итак, я добавил что-то вроде этого:

class Product < ActiveRecord::Base
  validate do |prod|
    prod.errors.add_to_base("Product price can't be blank") if prod.prod_price.blank?
  end
end

Но я также хочу проверить количество prod_price. Если я просто добавлю validate_numericality_of :prod_price и цена товара пуста, тогда появляются оба сообщения об ошибке (пусто и не является числом).

Как я могу получить сообщение об ошибке «не число», отображаемое только в том случае, если цена товара НЕ пуста?

Я пытался сделать

class Product < ActiveRecord::Base
  validate do |prod|
    prod.errors.add_to_base("Product price can't be blank") if prod.prod_price.blank?
    if !prod.prod_price.blank?
       prod.errors.add_to_base("Product price must be a number") if prod.prod_price.<whatdo i put here>
    end
  end
end

Кроме того, как я могу получить пользовательское сообщение для «не число». Я хочу скрыть показ моего имени столбца пользователю.

Ответы [ 5 ]

5 голосов
/ 25 декабря 2013

Принимаемый в настоящее время ответ работает, но вот управляемый данными способ сделать это с помощью Rails 'i18n:

Добавление allow_blank: true к validates_numericality_of позаботится о пустой проблеме.

Затем вы можете использовать i18n для автоматического перевода имен атрибутов для вас (документы здесь ). Для prod_price вы просто добавите это к en.yml:

en:
  activerecord:
    attributes:
      product:
        prod_price: "Product price"

Теперь для должна быть часть , мы можем снова использовать i18n. От документы :

Сообщения об ошибках проверки Active Record также могут быть легко переведены. Active Record предоставляет вам пару пространств имен, где вы можете разместить переводы сообщений, чтобы предоставлять разные сообщения и переводы для определенных моделей, атрибутов и / или проверок.

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

Итак, теперь мы можем добавить это к en.yml таким образом:

en:
  activerecord:
    errors:
      models:
        product:
          attributes:
            prod_price:
              not_a_number: "must be a number"

Теперь, когда проверка не пройдена, она объединит их, чтобы получить: Цена продукта должна быть числом .

5 голосов
/ 28 января 2010

Вы можете иметь собственные сообщения без написания собственного метода проверки. Просто добавьте :message:

validates_presence_of :prod_price, :message => "Product price can't be blank"

Если вы хотите пропустить проверку численности, когда prod_price отсутствует, добавьте: allow_nil:

validates_presence_of :prod_price, :message => "Product price can't be blank" validates_numericality_of :prod_price, :allow_nil => true

Тогда проверка чисел не будет выполняться, если отсутствует prod_price.

EDIT:

Подождите, вы не хотите, чтобы имя поля отображалось в сообщении об ошибке, не так ли? Я пропустил это. Так что вам все-таки понадобится пользовательская проверка.

РЕДАКТИРОВАТЬ # 2:

Хорошо, как насчет этого:

protected

def validate
  if prod_price.blank?
    errors.add "Product price can't be blank"
  else
    begin
      Integer(attributes_before_type_cast["prod_price"])
    rescue ArgumentError  
      errors.add "Product price must be a number"
    end
   end
end
1 голос
/ 28 января 2010

По многим причинам, если вам не нужно делать что-то необычное, вы должны прикреплять сообщения об ошибках к определенным полям (проще выполнять модульные тесты, легче модифицировать ошибки позже, вы можете отображать маркеры рядом с недопустимыми полями, если вы хочу и т. д.). Я думаю, что то, что вы хотите сделать, может быть достигнуто с помощью этого:

class Product < ActiveRecord::Base
  validates_numericality_of :name, :if => lambda{ |obj| obj.prod_price? }
  validates_presence_of :name
end
0 голосов
/ 28 января 2010
if prod.prod_price.blank?
  prod.errors.add_to_base("Product price can't be blank") 
elsif prod.prod_price.match(/[^\d]/)
  prod.errors.add_to_base("Product price must be a number")
end
0 голосов
/ 28 января 2010

Я взял этот подход из другого вопроса SO

class User < ActiveRecord::Base

  HUMANIZED_ATTRIBUTES = {
    :email => "E-mail address"
  }

  def self.human_attribute_name(attr)
    HUMANIZED_ATTRIBUTES[attr.to_sym] || super
  end

end

Таким образом, мне не нужно писать свое сообщение для каждого поля. Я просто изменяю имя файла, представленное пользователю

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