Application Controller中的引擎路由

Oli*_*ves 12 rails-routing rails-engines ruby-on-rails-3

我在我的主应用程序的应用程序控制器中有一个before_filter挂钩,它执行以下操作:(它不只是在闪存中放置一个链接,有一条消息,但它与问题无关,它只是访问路径中的方法)

class ApplicationController < ActionController::Base
  before_filter :set_link

  def set_link
    flash[:notice] = items_path
  end
end
Run Code Online (Sandbox Code Playgroud)

这适用于应用程序,但是当我进入控制器的引擎时,我得到了异常

No route matches {:controller=>"items", :action=>"index"}
Run Code Online (Sandbox Code Playgroud)

据我所知,在引擎中,除非加上前缀,否则路径助手都是引擎 main_app

所以将应用程序控制器中的方法更改为

  def set_link
    flash[:notice] = main_app.items_path
  end
Run Code Online (Sandbox Code Playgroud)

摆脱异常,但我真的不想这样做.是否有其他解决方案让引擎识别main_app路由?

编辑:

如果应用程序布局调用路径助手,也会发生这种情况.因此,如果引擎被设计为集成到main_app的布局中,那么这个问题也将在那里进行.

Ben*_*ret 19

可安装的引擎设计为像这样工作,即隔离主应用程序路由和引擎路由.

如果要合并两组路由,可以使用非隔离引擎.第一步是删除isolated_namespace引擎定义中的方法调用:

module MyEngine
  class Engine < Rails::Engine
    isolate_namespace MyEngine # remove this line
  end
end
Run Code Online (Sandbox Code Playgroud)

第二步是转换你的路线my_engine/config/routes.rb,你应该从这里:

MyEngine::Engine.routes.draw do
  # stuff that routes things
end
Run Code Online (Sandbox Code Playgroud)

对此:

Rails.application.routes.draw do
  # stuff that routes things
end
Run Code Online (Sandbox Code Playgroud)

并删除mount应用程序路由中的方法调用:

App::Application.routes.draw do
  mount MyEngine::Engine => "/engine" # remove this line
end
Run Code Online (Sandbox Code Playgroud)

这样做的主要优点是:

  1. 不需要猴子补丁轨道.我知道设计是这样做的,但这可能是铁路中不存在引擎的日子里的剩余部分.

  2. 无需在应用程序路径中安装引擎.另一方面,如果你想更精确地控制插入点,这可能会适得其反,因为你的主要路线之后(或之前,我没有这个问题的答案)会调用所有引擎路线.

如果您正在寻找关于引擎的文档,那么Engine类rails文档是一个非常好的起点.如果您对该主题感兴趣,我强烈建议您阅读它们(如果您还没有).