Domanda

Sono in procinto di eseguire il refactoring di una parte della logica incorporata in un'applicazione Rails nel middleware e un fastidio che ho riscontrato è un'apparente mancanza di convenzioni su dove inserirli.

Al momento mi sono sistemato app/middleware ma potrei spostarlo altrettanto facilmente in vendor/middleware o forse vendor/plugins/middleware...

Il problema più grande è dover richiedere i singoli file nella parte superiore config/environment.rb

require "app/middleware/system_message"
require "app/middleware/rack_backstage"

oppure ricevo errori costanti non inizializzati sul file config.middleware.use linee.La situazione potrebbe complicarsi molto rapidamente.Preferirei che fosse nascosto da qualche parte in un inizializzatore.

C'è un posto convenzionale dove mettere questa roba?


La risposta specifica che sto cercando con questa taglia è: dove posso inserire le righe require in modo che non ingombrano il file Environment.rb ma vengano comunque caricate prima delle chiamate config.middleware.use? Tutto ciò che ho provato porta a errori costanti non inizializzati.


Aggiornamento:Ora che utilizziamo Rails 3.0, tratto un'app Rails come qualsiasi altra app Rack;inserire i file di codice per il middleware lib (o una gemma elencata in Gemfile) e sono richiesti e caricati config.ru.

È stato utile?

Soluzione

A partire da Rails 3.2, il middleware Rack appartiene alla directory app/middleware.

Funziona "out-of-the-box" senza alcuna istruzione require esplicita.

Esempio rapido:

Sto utilizzando una classe middleware chiamata CanonicalHost che è implementato in app/middleware/canonical_host.rb.Ho aggiunto la seguente riga a production.rb (Nota che la classe middleware viene fornita esplicitamente, anziché come una stringa tra virgolette, che funziona per qualsiasi file di configurazione specifico dell'ambiente):

config.middleware.use CanonicalHost, "example.com"

Se stai aggiungendo middleware a applicazione.rb, dovrai includere virgolette, come da Il commento di @mltsy.

config.middleware.use "CanonicalHost", "example.com"

Altri suggerimenti

Si può mettere in lib/tableized/file_name.rb. Finché la classe che si sta cercando di carico è rilevabile dal suo nome, Rails caricherà automaticamente il file necessario. Così, per esempio:

config.middleware.use "MyApp::TotallyAwesomeMiddleware"

Si dovrebbe tenere a:

lib/my_app/totally_awesome_middleware.rb

Rotaie catture const_missing e attemts ai file carico corrispondente alle costanti mancanti automaticamente. Basta assicurarsi che il nome corrisponde e sei sugo. Rails fornisce anche aiutanti nifty che ti aiuteranno a identificare il percorso di un file con facilità:

>> ChrisHeald::StdLib.to_s.tableize.singularize
=> "chris_heald/std_lib"

Così i miei stdlib vive in lib/chris_heald/std_lib.rb, ed è autocaricate quando mi riferisco nel codice.

Nel mio Rails 3.2 app, sono stato in grado di ottenere il mio TrafficCop middleware carico mettendolo a app/middleware/traffic_cop.rb, proprio come descritto @MikeJarema. Ho poi aggiunto questa linea al mio config/application.rb, come indicato:

config.middleware.use TrafficCop

Tuttavia, all'avvio dell'applicazione, ho continuato a ottenere questo errore:

uninitialized constant MyApp::Application::TrafficCop

Specificare esplicitamente spazio dei nomi root non aiutano:

config.middleware.use ::TrafficCop
# uninitialized constant TrafficCop

Per qualche motivo (che ho ancora da scoprire), a questo punto del ciclo di vita Rails, app/middleware non è stato incluso nei percorsi di carico. Se ho rimosso la linea config.middleware.use, e corse la console, ho potuto accedere alla costante TrafficCop senza alcun problema. Ma non poteva trovare in app/middleware al momento config.

Ho fissato questo racchiudendo il nome della classe middleware tra virgolette, in questo modo:

config.middleware.use "TrafficCop"

In questo modo, vorrei evitare l'errore uninitialized constant, dal momento che Rails non sta cercando di trovare la classe TrafficCop appena ancora. Ma, quando si inizia a costruire lo stack middleware, sarà constantize la stringa. A questo punto, app/middleware è nei percorsi di carico, e quindi la classe verrà caricato correttamente.

Per Rails 3:

#config/application.rb
require 'lib/rack/my_adapter.rb'
module MyApp
  class Application < Rails::Application
    config.middleware.use Rack::MyAdapter
  end
end

Non sono a conoscenza di una convenzione, ma perché non metterlo nella directory /lib? I file in là vengono automaticamente caricati Rails.

Si potrebbe creare un inizializzatore che richiede i file necessari e poi lasciare i file dove vuoi.

Secondo questo inizializzatori vengono eseguiti prima che il middleware montate.

La soluzione di lavoro che ho finora si sta muovendo il middleware richiede di config/middleware.rb e richiedendo che file in environment.rb, riducendola a una sola richiedere che posso vivere con.

mi piace ancora di sentire come altre persone hanno risolto questo problema apparentemente semplice di aggiungere middleware per Rails.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top