2016-01-28 14 views
13

Da die verschiedenen Edelsteine ​​in meinem System interagieren, habe ich einen Motor auf einer Schiene montiert. Ich habe vor kurzem begonnen, an einem neuen Juwel zu arbeiten, das einige Middleware-Funktionen bietet.Wie man Middleware von einem Motor in einem Motor verwendet

Art wie folgt aus:

BaseApp 
\ 
    Engine 
    \ 
    NewMiddlewareEngine 

# BaseApp/Gemfile 
gem 'Engine' 

# Engine/Gemfile 
gem 'NewMiddlewareEngine' 

# rake middleware output: 
[email protected][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 

Ich kann aber nicht die NewMiddlewareEngine scheint in Middleware zu zeigen, bis zu bekommen. Ich habe diese getestet Montage:

BaseApp 
\ 
NewMiddlewareEngine 

# BaseApp/Gemfile 
gem 'NewMiddlewareEngine' 

# rake middleware output: 
[email protected][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  

Und:

BaseApp 
\ 
Engine 

# BaseApp/Gemfile 
gem 'Engine' 

# rake middleware output: 
[email protected][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 

Welche funktionieren beide gut. Das Problem ist, wenn ich versuche, die NewMiddlewareEngine durch die Engine zu mounten.

Kann jemand so etwas konfigurieren?

Hier MyMiddlewareEngine Montage:

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

Können Sie die Ausgabe von 'Rake Middleware' – Tawan

+0

Ja, sicher. Ich habe den Middleware-Output für alle 3 Varianten aktualisiert. – SortingHat

+0

Haben Sie 'config.middleware.use NewMiddlewareEngine' im Initializer der anderen Engine ausprobiert? Der Initialisierer dieser Engine wird definitiv ausgeführt, also könnte es sein, dass Sie den Code dafür verwenden müssen. Dies sollte keine Änderungen am Anwendungscode erfordern. –

Antwort

0

Von Rails::Engine Edge API Dokumentation:

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 

Ich neige dazu, Schienen-Middleware konfigurieren auf der Anwendungsebene und nicht in einem Motor (als Trennung der Verantwortlichkeiten) laufen . Ich habe diesen Ansatz verwendet, um die Authentifizierung von einer Anwendung für montierte Schienen zu trennen (siehe example). Die Konfiguration hierfür ist in application.rb:

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

Sehen Sie irgendwelche Ausnahmen, wenn Sie Schienen-Konsole ausführen? Haben Sie versucht, den konstanten Namen wie oben anstelle eines String zu verwenden?

+0

Ist das application.rb von Ihrer Hauptanwendung? Ich wollte in der Lage sein, nur die 1 Zeile in der Gemfile zu haben, um meine Engine im Gegensatz zu anderen Bearbeitungen enthalten zu lassen. Und ich habe versucht, ein Railtie für den Grund zu verwenden, den Sie erwähnten. Ich denke, ein Railtie wird die Konfiguration über die Anwendung hinweg ermöglichen. Das Seltsame ist, dass ich eine Engine in eine Engine setze, die schließlich auf einer Anwendung läuft (ich habe versucht, das mit dem Diagramm zu zeigen). – SortingHat

+0

Ich denke, Sie sind in dem Sinne richtig, dass dies auf der Anwendungsebene konfiguriert werden muss. Da scheinbar das geschieht, initialisiert das Railtie, worauf es montiert ist, aber wenn es eine zweite Schicht tief ist, wird die Railtie-Initialisierung niemals aufgerufen. MyMiddlewareEngine muss irgendwie für die Hauptanwendung und nicht für die Engine konfiguriert werden, in die es eingebunden ist. – SortingHat

+0

Also, wenn ich meine Struktur von 'App mit Engine mit MiddlewareEngine' verlassen und in App/config/application.rb add 'config.middleware.use NewMiddleWareEngine' Ich bekomme 'NameError: nicht initialisierte Konstante App :: Application :: MiddlewareEngine'. Das Setup wird also nicht an die Haupt-App weitergegeben. Ich werde versuchen, mit den Includes zu spielen. – SortingHat