How to Find Out the Current Route in Rails

How can I find out the current route in Rails?

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

How to get the current route in rails

To retrieve the URLs:

# Current URL:
request.original_url

# Current relative URL:
request.request_uri

Additionally, you can check with the current_page method whether you are in a certain route.

current_page?(my_path)
# => true / false

For Rails 4 use:

# Current URL:
request.original_url

# Current relative URL:
request.fullpath

How to get the current view path in rails?

Depending on what you actually need, one of these might help:
request.url, request.path

if you to know the controller/action being called:
controller_name, action_name

Rails find current route namespace

You should be able to add additional params to your namespace, like:

namespace :admin, admin: true do
# ...
end

Then within that you'll get params[:admin] being true.

This might require defaults: { admin: true } to work, it's not clear from the docs.

How to find current abstract route in Rails middware

You need to pass ActionDispatch::Request or Rack::Request to recognize method. Here is an example from another app:

main:0> req = Rack::Request.new("PATH_INFO" => "/customers/10", "REQUEST_METHOD" => "GET")
main:0> Rails.application.routes.router.recognize(req) { |route, params| puts params.inspect }; nil
{:controller=>"customers", :action=>"show", :id=>"10"}
=> nil

The same will work with ActionDispatch::Request. Inside middleware, you can easily create this object:

request = ActionDispatch::Request.new(env)

And if you need more information about recognized route, you can look into that route object that is yielded to block, by recognize method.

Update

The above solution will work for normal Rails routes, but since you only have spree engine mounted you need to use different class

request = ActionDispatch::Request.new(env)
Spree::Core::Engine.routes.router.recognize(request) { |route, params|
puts params.inspect
}

I guess the best would be find a generic solution that works with any combination of normal routes and engines, but this will work in your case.

Update #2

For more general solution you need to look at the source of Rails router, which you can find in ActionDispatch module. Look at Routing and Journey modules. What I found out is that the returned route from recognize method can be tested if this is a dispatcher or not.

request = ActionDispatch::Request.new(env)
Rails.application.routes.router.recognize(req) do |route, params|
if route.dispatcher?
# if this is a dispatcher, params should have everything you need
puts params
else
# you need to go deeper
# route.app.app will be Spree::Core::Engine
route.app.app.routes.router.recognize(request) do |route, params|
puts params.inspect
}
end
end

This approach will work in case of your app, but will not be general. For example, if you have sidekiq installed, route.app.app will be Sidekiq::Web so it needs to be handled in different way. Basically to have general solution you need to handle all possible mountable engines that Rails router supports.

I guess it is better to build something that will cover all your cases in current application. So the thing to remember is that when initial request is recognized, the value of route yielded to black can be a dispatcher or not. If it is, you have normal Rails route, if not you need to recursive check.

Rails, how to get the route name from the actual request (routing reverse lookup)

IMHO you could use the code explained by KinOfCain on How can I find out the current route in Rails?

Rails.application.routes.router.recognize(request){ |route, matches, parameters| puts route.name }

The router is not storing the route recognized in any place at least I wasn't able to find it



Related Topics



Leave a reply



Submit