Displaying form errors with nested resources

Hi all,

I’m having trouble with getting ActiveRecord validation errors to
display on a form which submits to an action in a nested resource.
This is for a basic blog application - the form in question is for
adding a new comment via the post’s show action. The problem seems to
be that the error messages generated by ActiveRecord don’t persist
through requests, so if validation fails and I redirect_to the
original post’s show action, the messages are lost. From what
information on this I’ve been able to find, the solution seems to be
to render the original view directly from the comment’s create action.
This is where I’m running into trouble. Every method I try for this
gives me a different error. Here is what I’ve tried:

render :action => ‘…/posts/show’ ( as someone suggested on
http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/74abb8eec08d2567/9c72f80d36c0697a
)

Which results in: Missing template comments/…/posts/show in view path
app/views

render :template => ‘posts/show’

Which results in: Missing template comments/_post.erb in view path app/
views (It’s looking for the post partial under the comments views
instead of under the posts views. using render :file with the same
value results in the same error as well.)

What is the proper way to display the original page and have the
validation errors persist? Thanks in advance!

I’ve made a little progress. Here is the current state of my issue:

http://pastie.org/614179

Solved with the help of the folks on IRC. :slight_smile:

Here is what it took, using the paste in the last message as the
starting point:

  1. Change “Comment.new” to “@comment” on in the form_for block.
  2. Set @comment as a new comment object in the post’s show action, so
    that a blank comment is used when the page is first rendered, but
    @comment holds the value of the submitted comment as set by the
    comments controller when the page is rendered again.
  3. Call the comment partial with this syntax:

:collection => @post.comments.reject(&:new_record?)

This excludes the unsaved record from the loop. The same method is
also used to prevent the entire comments section from being displayed
when the invalid comment is the only one present:

unless @post.comments.reject(&:new_record?).empty? …

Hopefully this will help someone else.