5

我正在尝试结合使用本文概述的方法来确定url_for当前路径是否在已安装的引擎中,但是我很难弄清楚如何准确使用Journey::Path::Pattern(这是mounted_path概述的方法返回的内容)在另一篇文章中)。

class Rails::Engine
  def self.mounted_path
    route = Rails.application.routes.routes.detect do |route|
      route.app == self
    end
    route && route.path
  end
end

除了官方文档之外,似乎没有太多关于它的讨论,这并不是特别有用。我确定解决方案相对简单,我尝试编写的辅助方法的要点如下:

def in_engine? engine
  current_url.include?(engine.mounted_path)
end

编辑:

我的一些引擎被挂载为子域,而一些被挂载在应用程序本身中,这使我无法简单地检查当前子域是否与挂载路径相同,或者使用path_for.

4

1 回答 1

0

不完全是一个解决方案,但也许是一个有用的线索。

我发现你的问题很有趣,所以我开始深入研究 Rails 源......多么可怕但有启发性的旅行:D

事实证明,Rails 的路由器有一个接受 a作为参数的recognize 方法request,并产生与请求匹配的路由。

由于路由具有app可以与引擎进行比较的方法,并且您可以访问request对象(考虑到 http 方法、子域等),如果您了解如何直接访问路由器实例,您应该能够按照以下方式做一些事情:

  def in_engine?(engine)
    router.recognize(request) do |route,*| 
      return true if route.app == engine
    end
    false
  end

编辑

我想我发现了,但是我手头没有rails应用程序来测试它已经很晚了:(

  def in_engine?(engine)
    # get all engine routes. 
    # (maybe possible to do this directly with the engine, dunno)
    engine_routes = Rails.application.routes.set.select do |route| 
      route.app == engine
    end
    !!engine_routes.detect{ |route| route.matches?(request) }
  end

编辑

另外,也许更简单的解决方法是这样做:

在您的主应用程序中

  class ApplicationController < ActionController::Base
    def in_engine?(engine)
      false
    end
    helper_method :in_engine?
  end

然后在引擎的应用程序控制器中

  def in_engine?(engine)
    engine == ::MyEngine
  end
  helper_method :in_engine?
于 2013-10-31T21:14:22.830 回答