我有一个引擎(由我/我工作的公司开发),我们在几个不同的项目中使用它。我刚刚将它转换为使用带有资产管道的 rails 3.1 并且一切似乎都在工作......在大多数情况下。
我的问题是我需要UsersController
使用一些特定于应用程序的香料来扩展 的功能,但我不确定最好的方法。引擎没有定义Users#show
动作,但是这个应用确实需要它,所以我在路由文件中添加了:
JobEngine::Application.routes.draw do
root :to => 'home#index'
resource :users, :only => [:show]
resources :jobs, :only => [:show]
end
然后在我的应用程序中创建了 UsersController:
class UsersController < MyEngine::UsersController
def show
end
end
然后我做了一个users/show.html.haml
视图,我把它剥离了,只显示一个问题行:
= link_to "Somewhere", job_path(3)
这给了我一个错误,上面写着undefined method 'job_path' for #<#<Class:0x00000102d69900>:0x00000102d4ed30>
这很奇怪,因为在我让我的应用程序UsersController
继承MyEngine::UsersController
它之前工作得很好。
当我rake routes
在控制台中进行操作时,有以下几行:
users GET /users(.:format) {:action=>"show", :controller=>"users"}
job GET /jobs/:id(.:format) {:action=>"show", :controller=>"jobs"}
我可以将类定义更改为:
class UsersController < ApplicationController
然后链接工作得很好。但是,引擎的控制器MyEngine::UsersController
已经继承自ApplicationController
. 我可以将代码放入我的应用程序ApplicationController
(如 a before_filter
),它会按预期运行,所以我知道我的类定义最终会影响我的应用程序ApplicationController
,为什么 job_path 助手不起作用?
当我将显示操作更改为:
def show
job_path(3)
end
我得到错误:
ActionController::RoutingError (No route matches {:action=>"show", :controller=>"jobs", :id=>3}):
app/controllers/users_controller.rb:9:in `show'
这进一步让我感到困惑,因为现在它实际上确实将 job_path 识别为一种方法,但不知何故,路由器没有使用所有正确的参数选择去哪里。
我究竟做错了什么?扩展引擎控制器功能的正确方法是什么?我在这里看到了扩展引擎功能问题。
并遵循该代码示例,将我的类定义更改为重新打开MyEngine::UsersController
,但我仍然得到完全相同的结果job_path(NUMBER)
更新:
好的,我有点弄清楚发生了什么。假设您的引擎有一个 job_path 路由,而您的应用程序有一个 job_path 路由。如果您在通过引擎控制器访问的页面上,您可以使用 调用引擎的助手job_path
,但您也可以使用 调用主应用程序的助手main_app.job_path
。
同样,如果您在通过应用程序控制器之一访问的页面上,您可以my_engine.job_path
使用job_path
. 这是假设你有类似的东西mount MyEngine::Engine => "/my_engine", :as => 'my_engine'
。
当您从应用程序继承引擎控制器时,它会完全改变您的路由助手,使其认为您在控制器/视图生命周期中处于引擎的上下文中。所以要解决我的问题,我真正需要做的就是改变它main_app.job_path(3)
并且它可以工作。
我对这个解决方案并不完全满意,因为它感觉有点……奇怪。也许我在这个页面上有一个部分,将在一个单独的非继承页面上使用。现在链接助手将只适用于两个页面之一,但永远不会两个=\我在这里遗漏了什么......?