views:

31

answers:

1

My Rails 2.3 application has a User model and the usual controller actions. The edit form can be reached two ways: when a user edits his own profile from the home page, or when an admin user edits someone else's profile from users collection.

What I'd like to do is have the update action redirect back to the referred of the edit action, not the update action. If I do a simple redirect_to(:back) within update, it goes back to the edit form -- not good.

One solution is to forget entirely about referrers and redirect based on the current_user and the updated user: if they're the same, go back to the home page, else go to the users collection page. This will break if I ever add a third path to the edit form. It's doubtful I'll ever do this but I'd prefer a solution that's not so brittle.

Another solution is to store the referrer of edit form in a hidden field and then redirect to this value from inside the update action. This doesn't feel quite right, though I can't explain why.

Are there any better approaches? Or, should I stop worrying and go with one of the two I've mentioned?

+2  A: 

You should memorize the url in the session. This is how I implement this feature in my application.

Add these methods to your ApplicationController

def store_location location=nil
    session[:return_to] = location || request.request_uri
end

def redirect_back_or_default(default)
    redirect_to(session[:return_to] || default)
    session[:return_to] = nil
end

def http_referrer
  http_referer, request_path  = request.env["HTTP_REFERER"], 
                                request.env["REQUEST_PATH"]
  return nil  unless (http_referer and request_path and 
                      http_referer =~ Regexp.new("^#{SITE_ROOT}") and
                      http_referer != (SITE_ROOT + request_path))
  return http_referer    
end

In UserController edit/new action store the referrer.

before_filter :store_location, :only => [:new, :edit]

def store_location
  super http_referrer
end

In UserController create/update action return and reset referrer.

def create
  if @user.save
    flash[:notice] = "Successfully created the user."
    redirect_back_or_default root_url
  else
    render :action => 'new'
  end
end    

def update
  if @user.save
    flash[:notice] = "Successfully created the user."
    redirect_back_or_default root_url
  else
    render :action => 'new'
  end
end    
KandadaBoggu