如何使来自 Rails 3 引擎的路由可供主机应用程序使用?

发布于 2024-10-05 19:17:57 字数 1509 浏览 4 评论 0原文

我有一个 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

应用程序中的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)。

I have a Rails 3 application with several engines containing additional functionality. Each engine is a separate service that customers can purchase access to.

I am, however, having a problem with routes from the engines that aren't readily available to the controllers and views.

controller:

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 in engine:

MyEngineName::Engine.routes.draw do
  resources :classrooms
end

config/routes.rb in app:

Seabed::Application.routes.draw do
  mount MyEngineName::Engine => '/engine'
  ...
end

lib/my_engine_name.rb in engine:

module MyEngineName
  class Engine < ::Rails::Engine
  end
end

attempting to go to /classrooms/new results in

NoMethodError in Classrooms#new

Showing app/views/classrooms/_form.html.haml where line #1 raised:
  undefined method `hash_for_classrooms_path' for #<Module:0x00000104cff0f8>

and attempting to call classrooms_path from any other view results in the same error.
I can, however, call MyEngineName::Engine.routes.url_helpers.classrooms_path and get it working. I'm thinking I might have defined the routes wrong, but can't find another way that works.

Tried running the app with both Passenger (standalone and Apache module) and WEBrick (rails server). Using latest Rails from Git (7c920631ec3b314cfaa3a60d265de40cba3e8135).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

眼泪也成诗 2024-10-12 19:17:57

我遇到了同样的问题,并在 文档 中发现了这一点:

因为您现在可以在应用程序的内部安装引擎路由,您无法直接访问应用程序内引擎的 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

I had the same problem, and found this in the documentation:

Since you can now mount an engine inside application’s routes, you do not have direct access to Engine‘s url_helpers inside Application. When you mount an engine in an application’s routes, a special helper is created to allow you to do that. Consider such a scenario:

# config/routes.rb
MyApplication::Application.routes.draw do
  mount MyEngine::Engine => "/my_engine", :as => "my_engine"
  get "/foo" => "foo#index"
end

Now, you can use the my_engine helper inside your application:

class FooController < ApplicationController
  def index
    my_engine.root_url #=> /my_engine/
  end
end
胡渣熟男 2024-10-12 19:17:57

将引擎中的 config.routes 更改为:

Rails.application.routes.draw do  # NOT MyEngineName::Engine.routes.draw
  resources :classrooms
end

按照您的方式,路由仅在 MyEngineName::Engine 命名空间中可用,而在主机 Rails 的其余部分中不可用应用。

曾经有一篇博客文章提供了更多信息,但不幸的是它不再可用:

Change config.routes in your engine to:

Rails.application.routes.draw do  # NOT MyEngineName::Engine.routes.draw
  resources :classrooms
end

The way you have it, the routes are only available in the MyEngineName::Engine namespace and not in the rest of the host rails application.

There used to be a blog post with more info, but unfortunately it is no longer available:

很糊涂小朋友 2024-10-12 19:17:57

对我来说还可以帮助添加

require 'engine' if defined?(Rails)

到我的主 gem 文件(lib/.rb)。

很好的例子 - https://github.com/ human/Rails-3-engine-example/blob/master/lib/dummy.rb

For me also help to add

require 'engine' if defined?(Rails)

to my main gem file (lib/.rb).

Good example - https://github.com/mankind/Rails-3-engine-example/blob/master/lib/dummy.rb

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文