How can I find out the current route in Rails?

Viewed 205905

I need to know the current route in a filter in Rails. How can I find out what it is?

I'm doing REST resources, and see no named routes.

14 Answers

To find out URI:

current_uri = request.env['PATH_INFO']
# If you are browsing http://example.com/my/test/path, 
# then above line will yield current_uri as "/my/test/path"

To find out the route i.e. controller, action and params:

path = ActionController::Routing::Routes.recognize_path "/your/path/here/"

# ...or newer Rails versions:
#
path = Rails.application.routes.recognize_path('/your/path/here')

controller = path[:controller]
action = path[:action]
# You will most certainly know that params are available in 'params' hash

In rails 3 you can access the Rack::Mount::RouteSet object via the Rails.application.routes object, then call recognize on it directly

route, match, params = Rails.application.routes.set.recognize(controller.request)

that gets the first (best) match, the following block form loops over the matching routes:

Rails.application.routes.set.recognize(controller.request) do |r, m, p|
  ... do something here ...
end

once you have the route, you can get the route name via route.name. If you need to get the route name for a particular URL, not the current request path, then you'll need to mock up a fake request object to pass down to rack, check out ActionController::Routing::Routes.recognize_path to see how they're doing it.

I'll assume you mean the URI:

class BankController < ActionController::Base
  before_filter :pre_process 

  def index
    # do something
  end

  private
    def pre_process
      logger.debug("The URL" + request.url)
    end
end

As per your comment below, if you need the name of the controller, you can simply do this:

  private
    def pre_process
      self.controller_name        #  Will return "order"
      self.controller_class_name  # Will return "OrderController"
    end

You can see all routes via rake:routes (this might help you).

You can do this:

def active_action?(controller)
   'active' if controller.remove('/') == controller_name
end

Now, you can use like this:

<%= link_to users_path, class: "some-class #{active_action? users_path}" %>

I find that the the approved answer, request.env['PATH_INFO'], works for getting the base URL, but this does not always contain the full path if you have nested routes. You can use request.env['HTTP_REFERER'] to get the full path and then see if it matches a given route:

request.env['HTTP_REFERER'].match?(my_cool_path)
Related