【问题标题】:How to use Middleware from an Engine in an Engine如何在引擎中使用引擎中的中间件
【发布时间】:2016-05-06 10:16:22
【问题描述】:

由于不同的 gem 在我的系统中如何交互,我将一个引擎安装到 rails 应用程序上。我最近开始研究一个提供一些中间件功能的新 gem。

有点像这样:

BaseApp
\
  Engine
  \
   NewMiddlewareEngine

# BaseApp/Gemfile
gem 'Engine'

# Engine/Gemfile
gem 'NewMiddlewareEngine'

# rake middleware output:
user@laptop[BaseApp]$ bundle exec rake middleware
use Rack::Sendfile
use ActionDispatch::Static
use Rack::Lock
use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x6ebf30e1>
use Rack::Runtime
use Rack::MethodOverride
use ActionDispatch::RequestId
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use ActionDispatch::DebugExceptions
use ActionDispatch::RemoteIp
use ActionDispatch::Reloader
use ActionDispatch::Callbacks
use ActiveRecord::Migration::CheckPending
use ActiveRecord::ConnectionAdapters::ConnectionManagement
use ActiveRecord::QueryCache
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
use CatchJsonParseErrors
use ActionDispatch::ParamsParser
use Rack::Head
use Rack::ConditionalGet
use Rack::ETag
run BaseApp::Application.routes

但是,我似乎无法让 NewMiddlewareEngine 出现在中间件中。我已经测试过安装这个:

BaseApp
\
 NewMiddlewareEngine

# BaseApp/Gemfile
gem 'NewMiddlewareEngine'

# rake middleware output:
user@laptop[BaseApp]$ bundle exec rake middleware
use Rack::Sendfile
use ActionDispatch::Static
use Rack::Lock
use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x2f9795d8>
use Rack::Runtime
use Rack::MethodOverride
use ActionDispatch::RequestId
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use ActionDispatch::DebugExceptions
use ActionDispatch::RemoteIp
use ActionDispatch::Reloader
use ActionDispatch::Callbacks
use ActiveRecord::Migration::CheckPending
use ActiveRecord::ConnectionAdapters::ConnectionManagement
use ActiveRecord::QueryCache
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
use CatchJsonParseErrors
use ActionDispatch::ParamsParser
use Rack::Head
use Rack::ConditionalGet
use Rack::ETag
use NewMiddlewareEngine    # Notice it mounts fine on it's own
run BaseApp::Application.routes    

还有:

BaseApp
\
 Engine

# BaseApp/Gemfile
gem 'Engine'

# rake middleware output:
user@laptop[BaseApp]$ bundle exec rake middleware
use Rack::Sendfile
use ActionDispatch::Static
use Rack::Lock
use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x6ebf30e1>
use Rack::Runtime
use Rack::MethodOverride
use ActionDispatch::RequestId
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use ActionDispatch::DebugExceptions
use ActionDispatch::RemoteIp
use ActionDispatch::Reloader
use ActionDispatch::Callbacks
use ActiveRecord::Migration::CheckPending
use ActiveRecord::ConnectionAdapters::ConnectionManagement
use ActiveRecord::QueryCache
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
use CatchJsonParseErrors
use ActionDispatch::ParamsParser
use Rack::Head
use Rack::ConditionalGet
use Rack::ETag
run BaseApp::Application.routes

两者都可以正常工作。问题是当我尝试“通过”引擎安装 NewMiddlewareEngine 时。

有人知道如何配置这样的东西吗?

这是 MyMiddlewareEngine 安装:

module MyMiddlewareEngine
  class Railtie < Rails::Railtie
    initializer "add_my_middleware_engine_route_middleware" do |app|
      app.middleware.use 'MyMiddlewareEngine'
    end
  end
end

【问题讨论】:

  • 能否提供rake middleware的输出
  • 是的,当然。我更新为包含所有 3 个变体的中间件输出。
  • 您是否在其他引擎的初始化程序中尝试过config.middleware.use NewMiddlewareEngine?该引擎的初始化程序肯定正在运行,因此您可能需要在其中放置代码以使其工作。这不需要对应用程序代码进行任何更改。

标签: ruby-on-rails ruby middleware rails-engines rack-middleware


【解决方案1】:

来自Rails::Engine Edge API 文档:

 class MyEngine < Rails::Engine
   # Add a load path for this specific Engine
   config.autoload_paths << File.expand_path("../lib/some/path", __FILE__)

   initializer "my_engine.add_middleware" do |app|
     app.middleware.use MyEngine::Middleware
   end
 end

我倾向于将 Rails 中间件配置为在应用程序级别而不是在引擎中运行(作为职责分离)。我使用这种方法将身份验证与已安装的 rails 应用程序分开(请参阅example)。这个配置在application.rb:

 module MyApp
   class Application < Rails::Application
     ..
     config.middleware.use NewMiddlewareEngine

您在运行 rails 控制台时是否看到任何异常?您是否尝试过使用上述常量名称而不是 String

【讨论】:

  • 该 application.rb 来自您的主应用程序吗?我希望能够只在 Gemfile 中包含 1 行来包含我的引擎,而不是任何其他编辑。出于你提到的原因,我尝试使用 railtie。我认为 railtie 将允许跨应用程序进行配置。奇怪的是我将一个引擎放在一个最终在应用程序上运行的引擎中(我试图用图表来展示)。
  • 我认为你是对的,因为这需要在应用程序级别进行配置。因为似乎正在发生的是 railtie 初始化它所安装的东西,但是当它是第二层深度时,railtie 初始化永远不会被调用。 MyMiddlewareEngine 需要以某种方式配置为主应用程序,而不是它安装到的引擎。
  • 因此,如果我离开我的“带引擎的应用程序和中间件引擎”的结构并在 App/config/application.rb 添加“config.middleware.use NewMiddleWareEngine”我得到“NameError:未初始化的常量 App::应用程序::中间件引擎'。所以设置不会传播到主应用程序。我将尝试弄乱包含。
  • 你好像少了一个或多个requires
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多