【问题标题】:How can I find out the current route in Rails?如何在 Rails 中找到当前路线?
【发布时间】:2010-11-15 06:57:37
【问题描述】:

我需要知道 Rails 过滤器中的当前路线。我怎样才能知道它是什么?

我正在做 REST 资源,但没有看到命名路由。

【问题讨论】:

  • 你想用这个来完成什么?当您说“路线”时,您的意思是“URI”吗?
  • 关于如何在middleware 中获取它的任何想法。

标签: ruby-on-rails ruby routing


【解决方案1】:

我假设你的意思是 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

根据您在下面的评论,如果您需要控制器的名称,您可以这样做:

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

【讨论】:

  • 是的,我做到了,但我希望以更好的方式。我需要知道调用了哪个控制器,但我有相当复杂的嵌套资源。request.path_parameters('controller') 对我来说似乎无法正常工作。
  • self.controller_nameself.controller_class_name 中不需要self.
【解决方案2】:

您可以通过 rake:routes 查看所有路由(这可能对您有所帮助)。

【讨论】:

  • 我更喜欢打开一个路径无效的新选项卡,并从浏览器中查看所有路径/路由,因为这样更漂亮。但我认为这对获取当前路线没有帮助。
【解决方案3】:

要查找 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"

要找出路由,即控制器、动作和参数:

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

【讨论】:

  • 你会碰巧知道这是否是在 Rails 3 中相同/正确的方法吗?我确信它仍然可以访问,但我只是想确保我遵守最新的约定。
  • 当前控制器和动作在params[:controller]params[:action]中始终可用。但是,在它之外,如果您想识别路线,则此 API 不再可用。它现在已经转移到ActionDispatch::Routing,我还没有尝试过recognize_path
  • 查找当前路径最好使用request.path
  • 您也可以调用request.env['ORIGINAL_FULLPATH'] 在路径中包含可能的参数,请参阅下面的答案。
  • current_uri = request.env['PATH_INFO'] 如果在路由中设置了 trailing_slash,则不起作用
【解决方案4】:

如果您想对视图中的某些内容进行特殊处理,可以使用current_page?,如下所示:

<% if current_page?(:controller => 'users', :action => 'index') %>

...或者一个动作和 id...

<% if current_page?(:controller => 'users', :action => 'show', :id => 1) %>

...或命名路线...

<% if current_page?(users_path) %>

...和

<% if current_page?(user_path(1)) %>

因为current_page? 需要控制器和动作,所以当我只关心控制器时,我会在ApplicationController 中创建current_controller? 方法:

  def current_controller?(names)
    names.include?(current_controller)
  end

并像这样使用它:

<% if current_controller?('users') %>

...这也适用于多个控制器名称...

<% if current_controller?(['users', 'comments']) %>

【讨论】:

  • 注意你也可以使用current_page?带有命名路由:current_page?(users_path)
  • 对themario 很好。我不知道。我正在修改答案。
  • controller_nameaction_name 也适用于这类事情的助手和视图。
  • 在视图中你也可以只做 这样你就不需要控制器了
  • 在 Rails 6(可能早在 Rails 4 或 5)中,您可以简单地提供一个活动记录对象:current_page?(@user) 或集合 current_page?(@users)。 Rails 在后台使用polymorphic_path 从给定的活动记录对象生成路径。很整洁!
【解决方案5】:

在 rails 3 中,您可以通过 Rails.application.routes 对象访问 Rack::Mount::RouteSet 对象,然后直接对其调用识别

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

获得第一个(最佳)匹配,以下块形式循环匹配的路由:

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

一旦你有了路线,你可以通过 route.name 获得路线名称。如果您需要获取特定 URL 的路由名称,而不是当前请求路径,那么您需要模拟一个假请求对象以向下传递到机架,查看 ActionController::Routing::Routes.recognize_path 以查看他们是怎么做的。

【讨论】:

  • 错误:undefined method 'recognize' for #&lt;Journey::Routes:0x007f893dcfa648&gt;
【解决方案6】:

你可以这样做

Rails.application.routes.recognize_path "/your/path"

它适用于 rails 3.1.0.rc4

【讨论】:

  • 这将返回一个哈希,它是参数哈希。有什么方法可以实际获取路由对象吗?用名字和其他属性?
【解决方案7】:

您是否还需要参数

current_fullpath = request.env['ORIGINAL_FULLPATH'] # 如果你正在浏览 http://example.com/my/test/path?param_n=N # 那么 current_fullpath 将指向 "/my/test/path?param_n=N"

请记住,您可以随时致电&lt;%= debug request.env %&gt; 以查看所有可用选项。

【讨论】:

    【解决方案8】:

    基于@AmNaN 的建议(更多细节):

    class ApplicationController < ActionController::Base
    
     def current_controller?(names)
      names.include?(params[:controller]) unless params[:controller].blank? || false
     end
    
     helper_method :current_controller?
    
    end
    

    现在您可以调用它,例如在用于将列表项标记为活动的导航布局中:

    <ul class="nav nav-tabs">
      <li role="presentation" class="<%= current_controller?('items') ? 'active' : '' %>">
        <%= link_to user_items_path(current_user) do %>
          <i class="fa fa-cloud-upload"></i>
        <% end %>
      </li>
      <li role="presentation" class="<%= current_controller?('users') ? 'active' : '' %>">
        <%= link_to users_path do %>
          <i class="fa fa-newspaper-o"></i>
        <% end %>
      </li>
      <li role="presentation" class="<%= current_controller?('alerts') ? 'active' : '' %>">
        <%= link_to alerts_path do %>
          <i class="fa fa-bell-o"></i>
        <% end %>
      </li>
    </ul>
    

    对于usersalerts 路由,current_page? 就足够了:

     current_page?(users_path)
     current_page?(alerts_path)
    

    但是对于控制器的所有操作的嵌套路由和请求(与items 相比),current_controller? 对我来说是更好的方法:

     resources :users do 
      resources :items
     end
    

    第一个菜单项对于以下路线是有效的:

       /users/x/items        #index
       /users/x/items/x      #show
       /users/x/items/new    #new
       /users/x/items/x/edit #edit
    

    【讨论】:

      【解决方案9】:

      或者,更优雅:request.path_info

      来源:
      Request Rack Documentation

      【讨论】:

        【解决方案10】:

        我能在 2015 年提出的最简单的解决方案(使用 Rails 4 验证,但也应该使用 Rails 3)

        request.url
        # => "http://localhost:3000/lists/7/items"
        request.path
        # => "/lists/7/items"
        

        【讨论】:

        • 如果你想要视图中的id:
        • 这太棒了!以部分形式使用它以使用新参数重定向到当前页面。 &lt;form action="&lt;%= request.path %&gt;"&gt;
        【解决方案11】:

        request.url

        request.path #获取除基本url之外的路径

        【讨论】:

          【解决方案12】:

          您可以通过request.env['REQUEST_URI'] 来查看完整的请求 URI。它会输出如下所示的内容

          http://localhost:3000/client/1/users/1?name=test
          

          【讨论】:

            【解决方案13】:

            你可以这样做:

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

            现在,你可以这样使用:

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

            【讨论】:

              【解决方案14】:

              我发现批准的答案 request.env['PATH_INFO'] 可用于获取基本 URL,但如果您有嵌套路由,这并不总是包含完整路径。您可以使用request.env['HTTP_REFERER'] 获取完整路径,然后查看它是否与给定路由匹配:

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

              【讨论】:

                猜你喜欢
                • 2015-12-24
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2017-07-30
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多