0

I have a Post and Comment models. Comment belongs to a Post, and it is nested under Post in routes. Comments are posted from Posts#show. My routes look like this:

  resources :posts do
    resources :comments, only: [:create, :edit, :update, :destroy]
  end

If a user submits a comment that fails validation, the URL will look like this:

app.com/posts/:id/comments

If, for any reason, the user decides to hit enter in the address bar, there will be a routing error:

Routing Error
No route matches [GET] "/posts/21/comments"
Try running rake routes for more information on available routes.

This strikes me as some what odd. I understand why the error is happening, but it doesn't seem like it's a good idea for usability. Is there a way to prevent this from happening?

This becomes a bigger issue when doing friendly redirects. When a friendly redirect happens, Rails will redirect to that same URL using a GET request, again causing a routing error.

3 Answers 3

1

I think that the best way to avoid it is to create a route for this case and redirect to wherever make sense for your application. Something like the following:

match "/posts/:id/comments" => redirect {|params| "/posts/#{params[:id]}" }

Instead of that routing error, the user would be redirected to the post page.

Sign up to request clarification or add additional context in comments.

2 Comments

Interesting, what about in the case of a post request, or a user submission, is there a way to preserve the params and continue with post submission?
You can store the params in a cookie. Also you'd have to control whether you have to retrieve the stored data or not to try the submission again.
1

If your routes are

resources :posts do
  resources :comments, only: [:create, :edit, :update, :destroy]
end

then the URL for edit would be

app.com/posts/:post_id/comments/:id/edit

where :id is the comment. If validation fails, you should be redirecting back to this URL.

def update
  @post = Post.find(params[:post_id])
  @comment = @post.comments.find(params[:id])

  if @comment.update_attributes(params[:comment])
    redirect_to(edit_post_path(@post))
  else
    redirect_to(edit_post_comment_path(@post, @comment), :notice => "update failed")
  end
end

Better, since you are already at the correct edit URL,

...
  else
    flash[:error] = "Error - could not update comment"
    render :action => "edit"
  end

2 Comments

Just to be clear, your example update method, is do you mean this is in the posts controller or the comments controller?
I should have included the class name. It's the comments controller.
0

Not the best but the other solution may be to add comments through nested attributes of post.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.