F.error_messages in Rails 3.0

Rails 3.0 is not recommended to use f.error_messages and now it is necessary for the plugin to work correctly. However, I want to learn how to display error messages (new). I am following the getting started guide that uses an outdated method when implementing a comment 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 right way to do this (created by 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 last example, but which variable do I reference in the first to get error messages to create comments?

+41
ruby ruby-on-rails ruby-on-rails-3
Oct 06 2018-10-10
source share
6 answers

I just looked at the github docrails problems and they decided to remove f.error_messages and not explain how to do checks for comments.

0
Nov 12 2018-10-12T00:
source share

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

For example, here is the error_messages method that was implemented for my last project. Having implemented your own FormBuilder, you can follow the rules and styles of your web designer ... Here is an example that displays a list of errors in ul / li 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.

+22
Oct 29 '10 at 8:37
source share

I'm sure all you need to do is @post.comments link

So you can 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 out all the errors:

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

and then scroll through them in the display logic to display each of the comment errors.

+13
Oct. 06 2018-10-10
source share

This functionality exists as a standalone dynamic_form gem.

Add to your Gemfile

following:
 gem 'dynamic_form' 

On github page:

DynamicForm contains several help methods to help you deal with your Rails3 models:

  • 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 f.error_message_on .

+7
Nov 06 2018-12-12T00:
source share

Here is my solution for the whole error scene.

I created a part that simply uses the model variable that it would pass when rendering it:

 <%# app/views/errors/_error.html.erb %> <%= content_for :message do %> <% if model.errors.any? %> <ul> <% model.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> <% end %> <% end %> 

You can easily add dynamic html class names and / or names based on the model name, as well as generic ones.

I have settings where my error messages are displayed in one place in the layout file:

 <%# app/views/layouts/application.html.erb %> <%= yield :message %> 

If someone did not want this functionality to remove the content_for in partial, this would do the trick.
Then in fact you can simply write:

 <%= render 'errors/error', model: @some_model %> 

You could extend this even further by creating a batch that takes the collection and uses the error mentioned above:

 <%# app/views/errors/_collection.html.erb %> <% collection.each do |model| %> <%= render 'errors/error', model: model %> <% end %> 

Cut it off:

 <%= render 'errors/collection', collection: @some_model.some_has_many_association %> 

I like this way. It is simple, easy to manage / maintain and incredibly adaptable.
Hope this helps!

EDIT: Everything in HAML

 -# app/views/errors/_error.html.haml = content_for :message do - if model.errors.any? %ul - model.errors.full_messages.each do |msg| %li= msg 


 -# app/views/layouts/application.html.haml = yield :message 


 = render 'errors/error', model: @some_model 


 -# app/views/errors/_collection.html.haml - collection.each do |model| = render 'errors/errors', model: @some_model 


 = render 'errors/_collection', collection: @some_model.some_has_many_association 
+3
May 28 '13 at 17:27
source share

I assume that the array [@post, @post.comments.build] is passed only polymorphic_path inside form_for . This generates a sub-resource path for comments (e.g. /posts/1/comments in this case). So it looks like your first example uses comments as auxiliary resources for posts, right ?.

So the actual controller that will be called here is the CommentsController . The reason Lukas solution doesn't work for you may be because you are not actually using @ post.comments.build inside the controller when creating the comment (it doesn't matter that you use it in the view when you call form_for ). The CommentsController#create method should look like this (more or less):

 def create @post = Post.find(params[:post_id] @comment = @post.comments.build(params[:comment]) if(@comment.save) # you would probably redirect to @post else # you would probably render post#show or wherever you have the form end end 

Then you can use the code generated by the forests, replace only the @post instance @post with @comment in all lines except form_for .

I think it might also be a good idea to add @comment = @post.comment.build to the controller method that displays this form, and use form_for([@post, @comment], ...) so that the contents of the form appear in form if there are errors.

If this does not work, and you cannot figure it out, add your CommentsController#create method to the question.

+1
06 Oct 2018-10-10
source share



All Articles