Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the render method change the path for a singular resource after an edit?

OK so I have a User which has_one Template and I want a page which is basically just an edit view of the Template.

I have:

class TemplatesController < ApplicationController
  def edit
    @template = current_user.template
  end

  def update
    @template = current_user.template
    if @template.update_attributes(params[:template])
      flash[:notice] = "Template was successfully updated"
    end
    render :edit 
 end

end

Now the 'problem' is when I call render :edit I actually end up on /template.1 instead of /template/edit which is what I'd expect. Obviously if I call redirect_to :edit then I'd get the path I expect but I'd loose the object errors if there were any.

Is there a better way to do this?

Thanks!!

like image 760
neiled Avatar asked Dec 17 '10 22:12

neiled


2 Answers

Normally in an edit/update action pair you would only re-render the edit from update if there were errors, setting the flash accordingly. If you were already on template/1/edit (which is what I would expect), then the url logically won't change since you're telling the browser to simply render the text you're sending it. This is expected behavior. If you were successful in updating then you can redirect to show or index or wherever you need to go from there, and the flash will keep the notice text (that's what the flash is for) even though the model won't. Note that for a render action you need to use Flash.now so that the message won't persist on the next redirect.

def update
  @template = current_user.template
  if @template.update_attributes(params[:template])
    flash[:notice] = "Template was successfully updated"
    redirect_to(@template)
  else 
    flash.now[:error] = @template.errors[:base]
    render :edit
  end
end
like image 131
Dave Sims Avatar answered Nov 09 '22 19:11

Dave Sims


If you're using a singular resource, you want to use resolve in your routes. See this in the Rails Guides.

resource :geocoder
resolve('Geocoder') { [:geocoder] }
like image 23
Foosaurus Avatar answered Nov 09 '22 17:11

Foosaurus