2016-01-28 18 views
13

A causa del modo in cui le diverse gemme interagiscono nel mio sistema, ho un motore montato su un'applicazione rotaia. Recentemente ho iniziato a lavorare su una nuova gemma che fornisce alcune funzionalità del middleware.Come utilizzare il middleware da un motore in un motore

Un po 'come questo:

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 

Comunque, io non riesco a ottenere il NewMiddlewareEngine di presentarsi in middleware. Ho testato il montaggio questo:

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  

E:

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 

cui entrambi funzionano bene. Il problema è quando provo a montare NewMiddlewareEngine 'attraverso' il motore.

Qualcuno sa come configurare qualcosa di simile?

Ecco montaggio MyMiddlewareEngine:

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

È possibile fornire l'output di 'rake middleware' – Tawan

+0

Sì, di sicuro. Ho aggiornato per includere l'output del middleware per tutte e 3 le varianti. – SortingHat

+0

Hai provato 'config.middleware.use NewMiddlewareEngine' nell'inizializzatore dell'altro motore? L'inizializzatore di quel motore è sicuramente in esecuzione, quindi potrebbe essere il punto in cui è necessario inserire il codice per farlo funzionare. Questo non dovrebbe richiedere alcuna modifica al codice dell'applicazione. –

risposta

0

Da Rails::Engine Edge API documentazione:

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 

tendo a configurare rotaie middleware per l'esecuzione a livello di applicazione e non in un motore (come una separazione delle responsabilità) . Ho utilizzato questo approccio per separare l'autenticazione da un'applicazione di guide montate (vedere example). La configurazione di questo è in application.rb:

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

Vede qualche eccezioni quando si esegue console rotaie? Hai provato a utilizzare il nome costante come sopra invece di un String?

+0

È application.rb dall'applicazione principale? Volevo essere in grado di avere solo la riga 1 nel Gemfile per includere il mio motore rispetto a qualsiasi altra modifica. E ho provato a usare un railtie per il motivo che hai menzionato. Penso che un railtie consentirà la configurazione attraverso l'applicazione. La cosa strana è che sto mettendo un motore in un motore che finalmente gira su un'applicazione (ho provato a mostrarlo con il diagramma). – SortingHat

+0

Penso che tu abbia ragione, nel senso che questo deve essere configurato a livello di applicazione. Perché quello che sembra stia accadendo è che il railtie inizializza su cosa è montato, ma quando è un secondo livello in profondità l'inizializzazione del railtie non viene mai chiamata. MyMiddlewareEngine deve essere configurato in qualche modo per l'applicazione principale e non per il motore su cui è montato. – SortingHat

+0

Quindi se lascio la mia struttura di 'App with Engine with MiddlewareEngine' e in App/config/application.rb aggiungi 'config.middleware.use NewMiddleWareEngine' Ricevo 'NameError: costante non inizializzata App :: Application :: MiddlewareEngine'. Quindi l'installazione non si sta propagando all'App principale. Proverò a fare scherzi con gli include. – SortingHat

Problemi correlati