Я думаю, что лучший и самый гибкий способ - написать свой собственный помощник для полей формы. Отображение ошибок ввода пользователя варьируется от приложения к приложению и от макета к макету.
# 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' во всех ваших представлениях, то создайте пользовательский конструктор форм:)