Rails 3: Как не включать имя столбца в сообщение проверки без плагинов? - PullRequest
3 голосов
/ 27 декабря 2010

У меня есть следующая проверка:

validates_presence_of :price, :message => "my message"

и я получаю следующую ошибку, когда цена пуста:

Цена моего сообщения

Есть ли способ не включать имя столбца (price) в сообщение?

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

validates_presence_of :price, :message => "^ my message"

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

Цена ^ моё сообщение

Ответы [ 2 ]

3 голосов
/ 27 декабря 2010

Метод ^ определен в геме dynamic_form в Rails 3. Добавьте его в свой Gemfile, запустите bundle update, и он должен работать. Это также позволяет вам просто добавить <% = f.error_messages%> в ваши формы, чтобы избежать дополнительной работы по форматированию сообщений.

1 голос
/ 27 декабря 2010

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

# lib/required_attributes.rb
module ActiveModel
  module Validations
    module ClassMethods

      # ruby-1.9.2-head > Product.required_attributes
      #  => [:publisher_symbol_code, :price] 
      def required_attributes
        presence_validators = self.validators.find_all {|v| v.class == ActiveModel::Validations::PresenceValidator }
        presence_validators.map(&:attributes).flatten
      end

    end
  end
end


# application_helper.rb:

def mark_as_required
  content_tag :span, '*', :class => :required
end


def form_field_for(object, *args, &block)
  options = args.extract_options!
  attributes = args.map(&:to_sym)
  field_contents = capture(&block)
  classes = "form-field clear #{options[:class]}"

  if options[:hint]
    field_contents << content_tag(:p, options[:hint], :class => :inline_hint)
  end

  # Are there any required attributes?
  any_attribute_required = (object.class.required_attributes & attributes).present?

  if options[:label]
    object_name = object.class.to_s.underscore  # 'product'
    label_contents = "#{options[:label]}: #{mark_as_required if any_attribute_required}".html_safe
    label_html = label(object_name, attributes.first, label_contents, :class => 'form-label fl-space2')
    field_contents = label_html + field_contents
  end

  errors = attributes.inject([]) do |mem, attrib|
    mem << object.errors[attrib]
    mem
  end.flatten.compact.uniq

  if errors.present?
    classes << ' error' 
    field_contents << content_tag(:p, errors.join(', '), :class => :inline_errors)
  end

  content_tag(:div, field_contents, :class => classes)
end

А потом в поле зрения:

= form_field_for @product, :publisher_symbol, :label => "Symbol", :hint => "pick a product symbol" do
    = product_form.text_field :publisher_symbol, :size => 70

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

= form_field_for @product, :publication_year, :publication_month, :publication_day, :label => "Publication date" do
  = product_form.text_field :publication_year, :class => 'text fl', :size => 5
  = product_form.text_field :publication_month, :class => 'text fl', :size => 5
  = product_form.text_field :publication_day, :class => 'text fl', :size => 5

При возникновении ошибки ваш взгляд выглядит примерно так:

<div class="form-field clear error">
  <div class="field_with_errors">
    <label class="form-label fl-space2" for="product_publisher_symbol">Symbol: <span class="required">*</span></label>
  </div>
  <div class="field_with_errors">
    <input class="text fl" id="product_publisher_symbol" name="product[publisher_symbol]" size="70" type="text" value="">
  </div>                       
  <p class="inline_hint">pick a product symbol</p>
  <p class="inline_errors">can't be blank</p>
</div>

Этот код нуждается в некотором рефакторинге, но вы поняли идею. Если вы ленивее меня и не хотите вводить 'form_field_for' во всех ваших представлениях, то создайте пользовательский конструктор форм:)

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