Why does the code always throw a routing error?

skm376
skm376 used Ask the Experts™
on
The code below always throws a routing error. If I add an else statement and put the two lines after the if block in the else the code runs fine.  Why?

The best I can tell the reason for the error is @neighborhood is always equal to a new neighborhood even though the neighborhood you created has ALREADY been saved in the database. Really, really strange. After stepping through every line of rails my guess as to whats happening is respond_to is evaluating both execution paths (inside the if and outside). After it evaluates the second path it goes to redirect_to but at that time @neighborhood is equal to a new neighborhood and not the one saved in the database (because of the @neighborhood = @location.neighborhoods.new line). While stepping through I saw every line in the respond_to evaluated. Am I missing something? Why is this happening? Is it a Rails bug or am I just going crazy
def create
  @neighborhood = @location.neighborhoods.new( params[:neighborhood] )
  
  respond_to do |format|
    if ( @neighborhood.save )
      flash[:notice] = 'Neighborhood was successfully created.'
      format.js { redirect_to( location_neighborhood_path(@location, @neighborhood) ) and return }
    end
    @neighborhood = @location.neighborhoods.new
    format.js { render :action => :new }
  end
end

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Change your end to an else is the way to go.

if saved
...
else
....
end

redirect_to (and render and render_to_string) DO NOT halt execution, so stuff after it will be run:

def show
  render
  @b = response.body
  ....
end

So, if you've called redirect/render once, then do it again, you'll get that DoubleRenderError.

Jamis explains it best
http://weblog.jamisbuck.org/2005/7/8/rails-tip-of-the-day

Author

Commented:
I'm not getting a double render error when running the above code.  I'm getting a failed to generate url error because my @neighborhood object is empty (ie it's equal to a new Neighborhood, not one that has an ID).  I know how to fix the problem...I want to know why.  I thought the 'and return' statement forced execution to stop in the if block.
Are you getting the route error in the view or on that format.js redirect line?

I'm with you, it sure seems like if the record is saved, it should return and skip the other code.
Commented:
I'm getting the error on the format.js redirect line.

 It feels like some sort of bug to me but I'm not sure if I just fundamentally mis-understand how respond_to works.  When I stepped through it I saw every line in the respond_to block (including stuff outside the if block) go through the debugger.  The last line executed was @neighborhood = @locations.neighborhoods.new before jumping to the redirect.  So, at that point the @neighborhood object was set to a new Neighborhood.  Is that how it's supposed to work?  I would think that code should never get executed/evaluated/whatever.
I'm with you, I don't think that's how it should work.

There must be some block magic going on. Maybe return is just exiting the respond_to block instead of the create action?

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial