Reputation: 35349
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.
Upvotes: 0
Views: 92
Reputation: 10081
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
Upvotes: 1
Reputation: 944
Not the best but the other solution may be to add comments through nested attributes of post.
Upvotes: 0
Reputation: 1131
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.
Upvotes: 1