Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

f.error_messages in Rails 3.0

Rails 3.0 deprecated f.error_messages and now requires a plugin to work correctly - I however want to learn how to display error messages the (new) native way. I am following the getting started guide, which uses the deprecated method when implementing the comments form. For example:

<h2>Add a comment:</h2>
<%= form_for([@post, @post.comments.build]) do |f| %>
  <%= f.error_messages %>
<div class="field">
  <% f.label :commenter  %><br />
  <%= f.text_field :commenter  %>
</div>
<div class="field">
  <%= f.label :body %><br />
  <%= f.text_area :body %>
</div>
<div class="actions">
  <%= f.submit %>
</div>
<% end %>

Here is the correct way to do it (as generated by the scaffold):

<%= form_for(@post) do |f| %>
  <% if @post.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2>

      <ul>
      <% @post.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>
 . . . 

I understand that I use the @post variable in the latter example, but what variable do I reference in the former to get the error messages for comment creation?

like image 888
Craig Smitham Avatar asked Oct 06 '10 13:10

Craig Smitham


3 Answers

I'm pretty sure all you'd need to do is reference @post.comments

So you could do something like:

<% @post.comments.each do |comment| %>
    <% if comment.errors.any? %>

    <% comment.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
    <% end %>

    <% end %>
<% end %>

Or just pull all the errors out out:

comment_errors = @post.comments.map(&:errors)

and then loop through them in your display logic to output each of the comment errors.

like image 30
Lukas Avatar answered Nov 20 '22 08:11

Lukas


The best and clean way to implement error_messages in your form is by implementing error_messages in a FormBuilder.

For example, here is the error_messages method I've implemented for my last project. By implemeting your own FormBuilder you can follow the rules and styles of your webdesigner... Here is an example that will output the errors list in ul/li's with some custom styles :

class StandardBuilder < ActionView::Helpers::FormBuilder
  def error_messages
    return unless object.respond_to?(:errors) && object.errors.any?

    errors_list = ""
    errors_list << @template.content_tag(:span, "There are errors!", :class => "title-error")
    errors_list << object.errors.full_messages.map { |message| @template.content_tag(:li, message) }.join("\n")

    @template.content_tag(:ul, errors_list.html_safe, :class => "error-recap round-border")
  end
end

Then in my forms :

= f.error_messages

And that's all.

like image 108
Nicolas Blanco Avatar answered Nov 20 '22 09:11

Nicolas Blanco


This functionality exists as a standalone gem dynamic_form.

Add the the following to your Gemfile

gem 'dynamic_form'

From the github page:

DynamicForm holds a few helpers method to help you deal with your Rails3 models, they are:

  • input(record, method, options = {})
  • form(record, options = {})
  • error_message_on(object, method, options={})
  • error_messages_for(record, options={})

It also adds f.error_messages and f.error_message_on to your form builders.

like image 7
Justin Tanner Avatar answered Nov 20 '22 08:11

Justin Tanner