我有一个Rails 3应用程序,其中包含多个包含其他功能的引擎。每个引擎都是一个单独的服务,客户可以购买。
但是,我对来自引擎的路径存在问题,这些路由不容易用于控制器和视图。
控制器:
class ClassroomsController < ApplicationController
..
respond_to :html
def index
respond_with(@classrooms = @company.classrooms.all)
end
def new
respond_with(@classroom = @company.classrooms.build)
end
..
end
app/views/classrooms/new.html.haml
:
= form_for @classroom do |f|
..
f.submit
引擎中的 config/routes.rb
:
MyEngineName::Engine.routes.draw do
resources :classrooms
end
app中的 config/routes.rb
:
Seabed::Application.routes.draw do
mount MyEngineName::Engine => '/engine'
...
end
引擎中的 lib/my_engine_name.rb
:
module MyEngineName
class Engine < ::Rails::Engine
end
end
尝试转到/classrooms/new
会导致
NoMethodError in Classrooms#new
Showing app/views/classrooms/_form.html.haml where line #1 raised:
undefined method `hash_for_classrooms_path' for #<Module:0x00000104cff0f8>
并尝试从任何其他视图调用classrooms_path
会导致同样的错误。
但是,我可以致电MyEngineName::Engine.routes.url_helpers.classrooms_path
并让它发挥作用。我想我可能已经错误地定义了路线,但找不到另一种有效的方法。
尝试使用Passenger(独立和Apache模块)和WEBrick(rails服务器)运行应用程序。使用Git中的最新Rails(7c920631ec3b314cfaa3a60d265de40cba3e8135
)。
答案 0 :(得分:26)
我遇到了同样的问题,并在documentation中找到了这个问题:
由于您现在可以在应用程序的路径中安装引擎,因此您无法直接访问Application中的Engine的url_helpers。在应用程序的路径中安装引擎时,会创建一个特殊帮助程序以允许您执行此操作。考虑这样的情况:
# config/routes.rb
MyApplication::Application.routes.draw do
mount MyEngine::Engine => "/my_engine", :as => "my_engine"
get "/foo" => "foo#index"
end
现在,您可以在应用程序中使用my_engine帮助程序:
class FooController < ApplicationController
def index
my_engine.root_url #=> /my_engine/
end
end
答案 1 :(得分:25)
将引擎中的config.routes
更改为:
Rails.application.routes.draw do # NOT MyEngineName::Engine.routes.draw
resources :classrooms
end
您拥有它的方式,路由只能在MyEngineName::Engine
命名空间中使用,而不能在其他主机应用程序中使用。
曾经有一篇博文有更多信息,但遗憾的是它不再可用:
答案 2 :(得分:2)
对我来说也有助于添加
require 'engine' if defined?(Rails)
到我的主要gem文件(lib / .rb)。
很好的例子 - https://github.com/mankind/Rails-3-engine-example/blob/master/lib/dummy.rb