Topic: [RESOLVED] Nested Routes and the render() Method... Is there a Way?

Hi everyone,

I am trying to use the render() method to re-render a form if the form fails to save. The form, cars/new.html.erb, is being accessed via the route /user/:user_id/cars/new. The create action for the Cars controller attempts to save both the Car and the UserCar object (which represents a user's car and JOINs a User with a Car) within a transaction. If either fails validation, then I want to re-render cars/new.html.erb, to display the validation errors so that the user can correct the mistakes.

I am currently using render :action => :new, but that routes the browser to /cars/new. I want it to route to the nested route, /users/:user_id/cars/new. Is this possible with the render() method?

Thanks for the help in advance.

Last edited by johnnyicon (2008-12-13 18:56:25)

Re: [RESOLVED] Nested Routes and the render() Method... Is there a Way?

I don't think render is the best approach..I think redirect_to makes a bit more sense in this scenario. I'd say the best way to handle it would be to define the routes as resources, kinda like this..

map.resources :users do |users|
users.resources :cars
end

Then you have nice clean restful routes to redirect to should the form submission fail..

flash[:notice] #you messed up the form
redirect_to new_user_car_path (or whatever the route is, it's kinda late and my mind is fried)

Re: [RESOLVED] Nested Routes and the render() Method... Is there a Way?

I'm having this same problem w/ render.  Am I wrong in saying that redirect_to clears out the form that had the errors in it when the user submitted it?  So if the user is at /forums/1/user/new and the user does:

redirect_to new_league_player_path(params[:forum_id])

the user loses all the info that he had entered on the form.  Another consequence is that we can no longer display user.errors to the user.

Re: [RESOLVED] Nested Routes and the render() Method... Is there a Way?

After reading my explanation I realize the flow is not quite clear:

1) user fills out for at /forums/1/user/new
2) controller tries to save new user, but user validation fails
3) controller would like to render or redirect_to /forums/1/user/new with form data that user had entered still intact, along w/ user.errors to display on the page
4) redirect_to clears this info, so is not useful in the nested route

Re: [RESOLVED] Nested Routes and the render() Method... Is there a Way?

watchdogtimer wrote:

I'm having this same problem w/ render.  Am I wrong in saying that redirect_to clears out the form that had the errors in it when the user submitted it?  So if the user is at /forums/1/user/new and the user does:

redirect_to new_league_player_path(params[:forum_id])

the user loses all the info that he had entered on the form.  Another consequence is that we can no longer display user.errors to the user.

If you make the form page use the values from @user and the new (but not yet saved) @car object, then they will be put into the fields when you re-render it.  If you redirect, you will make a new object from scratch and the user will be back to the start.  So you should definitely render rather than redirect - you hsould just be able to do

render :template => "new"

Last edited by Max Williams (2008-12-11 13:12:30)

###########################################
#If i've helped you then please recommend me at Working With Rails:
#http://www.workingwithrails.com/person/ … i-williams

Re: [RESOLVED] Nested Routes and the render() Method... Is there a Way?

looking at the rdoc for template, this doesn't seem to handle nested routes

From Rdoc
"# Renders the template located in [TEMPLATE_ROOT]/weblog/show.r(html|xml) (in Rails, app/views/weblog/show.erb)
  render :template => "weblog/show"
End Rdoc

So, one would not have a temaplate located at /forums/1/users/new...

thanks for the response,
tom

Re: [RESOLVED] Nested Routes and the render() Method... Is there a Way?

Thanks for the responses everyone. I really appreciate it.

So have we come to a conclusion that it is NOT possible to use the render method with a nested route? It certainly seems like it from the responses.

Re: [RESOLVED] Nested Routes and the render() Method... Is there a Way?

this should not be a problem at all.

what does the form_for of this form look like? i guess there's the source of the problem.

render doesn't redirect anywhere, so if /cars/new shows up in the browsers address bar after you re-render the form, it's because you specified the wrong target url in the form that was submitted. as that is the url thats shown in the browser.

my guess would be that you didn't use the nested route in the form_for()

Re: [RESOLVED] Nested Routes and the render() Method... Is there a Way?

Duplex wrote:

what does the form_for of this form look like?

form_for :car, :url => new_user_car_path(@current_user) do |form|

Cars controller
def create
  render :new
end

When I click the submit button on the form, I get the following error:

Only get, put, and delete requests are allowed.

The error traces back to the recognition_optimisation.rb class which will only succeed if it recognizes the URI. It is failing because it doesn't recognize the URI and doesn't support the HTTP method for such a URI.

Last edited by johnnyicon (2008-12-13 18:26:03)

Re: [RESOLVED] Nested Routes and the render() Method... Is there a Way?

why do you target the form_for to the new action?!?

<%form_for [@current_user,@car] do |form|%>
#or
<%form_for @car, :url => user_cars_path(@current_user) do |form|%>
#....

#controller
def new
  @car = Car.new
end

def create
#...code
  else
    render :action => "new"
  end
end


render has *nothing* to do with which URL shows up, as it only renders the HTML. the url that shows up is specified in the form on the previous page

Re: [RESOLVED] Nested Routes and the render() Method... Is there a Way?

Duplex wrote:

why do you target the form_for to the new action?!?

I just did that because I was lazy. The whole point was to re-render the form if validation failed. I was lazy to type out the validation code. smile

I'll give your suggestion above a shot. I'll let you know the results. Thanks by the way.

Re: [RESOLVED] Nested Routes and the render() Method... Is there a Way?

pointing a form that should send to the create action to the new action is not lazy, it's simply wrong wink

anyways, your error lies in the form_for setup. not in the routes config or anything else.

Re: [RESOLVED] Nested Routes and the render() Method... Is there a Way?

You are a savior! Thank you!

Duplex wrote:

pointing a form that should send to the create action to the new action is not lazy, it's simply wrong wink

I misread that. I thought you were referring to my controller code. I see now looking at the defined routes why using new_user_cars_path is wrong; there isn't a route defined for the POST method. The route is on the user_cars_path.

Is there any more documentation on this syntax:

Duplex wrote:

<%form_for [@current_user,@car] do |form|%>

I'm asking specifically about the array syntax. Does the order of the parameters matter?

Re: [RESOLVED] Nested Routes and the render() Method... Is there a Way?

yes, the order does matter. it's the order of the nesting.
:users has :cars nested under it, so [@current_user,@car]

and if @car is a new, unsaved record, it will pick the url (&HTTP verb) for the create action, if it's an existing record, it will send to the update action. Rails is clever wink