How to get segment keys from a Rails 3 route?
I need to determine the number of route segment keys in the current path for an application I'm working on, and despite digging around for a bit in the related Rails 3 source files, I can't figure it out.
I know how to use url_for
and request
to build a path from the current route, but I don't know how to actually get to the ActionController::Routing::Route
that maps to the route url_for
is using. If I can get an instance of the route I need, I can just call Route#segment_keys and get what I need.
If anybody is interested, the reason I'm doing this is so I can toggle between resources with a select dropdown and stay on the current view that applies to the currently selected resource, but only if the current path doesn't contain nested开发者_运维百科 paths (i.e. toggle /resources/1/edit
to /resources/2/edit
but do not toggle between /resources/1/subresources/1
to /resources/2/subresources/1
because subresource
number 1 is not a child of resource
2).
I had a case where I need to do something like this, so I added a method in my application_helper.rb:
def display_sub_navigation
if admin_signed_in?
url_path = request.fullpath.split("/")
if url_path.size > 3 && File.exists?( Rails.root.join("app/views/shared/_#{url_path[2]}_sub_navigation.html.erb") )
render :partial => "/shared/#{url_path[2]}_sub_navigation"
end
end
end
As you can see using the request.fullpath.split("/") creates an array I assign to url_path. From here, I can extract out what I want or count the number of elements in the array. I hope this pushes you in the right direction.
Do you need all the segment keys or just a certain kind?
I was able to get just the literal keys with this code
Rails.application.routes.routes.collect do |i|
i.path.spec.grep(Journey::Nodes::Literal).collect(&:left)
end
That got me just just the array of literal segments - I bet you could modify that to count the number of segment keys that exist (or do it once for literals and once for the symbols) Journey::Nodes::Cat
supports to_s
which will give you the original string used to construct the route and to_regexp
which will give you a regex you can run against request.path
Would something like this help? It resolves a path to a route hash.
> uri = URI("http://localhost:3000/items/2015/3") # some URI for your request, or the URL/Path in question
> Rails.application.routes.recognize_path(uri.path)
=> {:controller=>"items", :action=>"index", :year=>"2015", :month=>"03"}
精彩评论