Re: Customize validation output

Jeff Lewis
Fri, 31 Dec 2010 19:34:47 -0000

Hi djangst,

When model validation rules result in errors, those errors are
basically made available to you as an ordered hash where the keys are
symbols of the attribute names and the values are strings/arrays of
the error(s) for the attribute.

So if you had some model foo.rb:

class Foo < ActiveRecord::Base
  validates_presence_of :bar
  ...

  HUMAN_ATTR_NAMES = {
    :bar => "Bar Biz Baz",
    ...
  }

  def self.human_attribute_name(attr, options={})
    HUMAN_ATTR_NAMES[attr.to_sym] || super
  end
  ...
end

and tested in console:

$ ./script/rails console
Loading development environment (Rails 3.0.3)

> foo = Foo.create({})
 => #<Foo id: nil, ...

> foo.errors.any?
 => true

> foo.errors
 => {:bar=>["can''t be blank"], ....

> Foo.human_attribute_name(:bar)
 => "Bar Biz Baz"

So, if in some controller where you call @foo.create or @foo.save that
results in validation errors, then in the resulting view you could
grab those errors and do whatever you want with them, like:

...
<% if @foo.errors.any? %>
<%   @foo.errors.each do |attr, errs| %>

<%     attr_label = Foo.human_attribute_name(attr) %>
<%     err_msg = (errs.is_a?(Array)) ? errs.join('' and '') :
errs %>
<%= attr_label %> <%= err_msg %>
<%   end %>

<% end %>
...

It sounds like in your case, for each attr in your form, you''d want to
check if that attr had a validation err, and if so render that attr''s
error(s) along with the attr''s label and form element.

Note also that if you instead are calling @foo.create! or @foo.save!
in your controller, you''d get at that same errors ordered hash via
ActiveRecord::RecordInvalid:

$ ./script/rails console
...
> begin ; foo2 = Foo.create!({}) ; rescue ActiveRecord::RecordInvalid =>
rie ; rie.record.errors ; end
 => {:bar=>["can''t be blank"], ....

Cheers,

Jeff

On Dec 31, 6:07 am, djangst
<djan...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
wrote:
> The main problem is with styling adjacent elements, in this case a
> label. Or you might want to style a div that encloses an input and its
> label.
>
> On Dec 31, 4:13 am, ivanpoval
<ivanpo...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>
>
>
> > Hi,
> > Here is a couple of things that I found myself doing for customizing
> > the error messages: