ruby-on-railssessionrails-routinghelpermethods

Ruby on rails: previous url helper for entire application


Is there an easy way to write a helper method to always update the previously visited url in the session. I have tried the method below but the url saved is always the current one. I would like to be able to use this helper in all my controllers for redirect.

#application_controller.rb
class ApplicationController < ActionController::Base
before_filter :my_previous_url

def my_previous_url
    session[:previous_url] = request.referrer
  end

helper_method :my_previous_url
end

I have used it in my update method in the User controller as seen below but it always redirects to the same opened url (kind of looks like refresh was hit).

def update
    if current_user.admin == true and @user.update(user_params)
      redirect_to my_previous_url, notice: "Password for User #{@user.username} has Successfully been Changed."
      return
    elsif current_user.admin == false and @user.update(user_params)
      session[:user_id] = nil
      redirect_to login_path, notice: "Password for User #{@user.username} has Successfully been Changed. Please Log-In Using the New Password."
      return
    end
    respond_to do |format|
      if @user.update(user_params)
    changed = true
        format.html { redirect_to logout_path }
        format.json { render :show, status: :ok, location: @user }
      else
        format.html { render :edit }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end

Solution

  • request.referer isn't what you want here as it will be set on page redirects, thus losing the page you came from originally. I think that you have an implied requirement that it should return the last visited url which was different to the current one, is that the case? Also, i think that you would only want to set it for GET requests, otherwise you risk sending people back to the wrong url, since they will be sent back with a GET request. I'm assuming here that the purpose of this previous_url is to give people a "back" link.

    Also, don't get the method to set the previous_url mixed up with the method to read it back out again.

    I would do it like this:

    #application_controller.rb
    class ApplicationController < ActionController::Base
      before_filter :set_previous_url
      helper_method :previous_url
    
      def set_previous_url
        if request.method == :get && session[:previous_url] != session[:current_url]
          session[:previous_url] == session[:current_url]
          session[:current_url] = request.url          
        end 
      end
    
      def previous_url
        session[:previous_url]
      end
    end