Pergunta

Estou refatorando alguma lógica incorporada em um aplicativo Rails no middleware, e um aborrecimento que encontrei é uma aparente falta de convenção para onde colocá -los.

Atualmente eu decidi app/middleware Mas eu poderia facilmente movê -lo para vendor/middleware ou talvez vendor/plugins/middleware...

O maior problema é ter que exigir os arquivos individuais no topo de config/environment.rb

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

ou então eu recebo erros constantes não inicializados no config.middleware.use linhas. Isso pode ficar bagunçado muito rapidamente. Eu prefiro que isso estivesse escondido em um inicializador em algum lugar.

Existe um lugar convencional para colocar essas coisas?


A resposta específica que estou procurando com esta recompensa é: Onde posso colocar as linhas de necessidade para que elas não estejam confundindo o arquivo ambiente.rb, mas ainda são carregadas antes das chamadas config.middleware.use? Tudo o que tentei leva a erros constantes não inicializados.


Atualizar: Agora que estamos usando o Rails 3.0, trato um aplicativo Rails como qualquer outro aplicativo de rack; Os arquivos de código para o middleware entram lib (ou uma jóia listada em Gemfile) e são necessários e carregados em config.ru.

Foi útil?

Solução

A partir do Rails 3.2, o middleware do rack pertence ao diretório de aplicativos/middleware.

Funciona "pronta para uso" sem nenhuma declaração explícita.

Exemplo rápido:

Estou usando uma aula de middleware chamada Canonicalhost que é implementado em app/middleware/canonical_host.rb. Eu adicionei a seguinte linha para Production.rb (Nota que a classe de middleware é dada explicitamente, e não como uma string citada, que funciona para quaisquer arquivos de configuração específicos do ambiente):

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

Se você está adicionando middleware a Application.rb, você precisará incluir citações, conforme @comentário de mltsy.

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

Outras dicas

Você pode colocá -lo lib/tableized/file_name.rb. Enquanto a classe que você está tentando carregar for descoberta pelo nome do arquivo, os Rails carregarão automaticamente o arquivo necessário. Então, por exemplo:

config.middleware.use "MyApp::TotallyAwesomeMiddleware"

Você ficaria em:

lib/my_app/totally_awesome_middleware.rb

Os trilhos captrem const_missing e tentam carregar arquivos correspondentes às constantes ausentes automaticamente. Apenas certifique -se de que seus nomes correspondam e você esteja molho. O Rails ainda fornece ajudantes bacanas que ajudarão você a identificar o caminho para um arquivo facilmente:

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

Então meu stdlib vive em lib/chris_heald/std_lib.rb, e é transportado automaticamente quando eu o faço referência no código.

No meu aplicativo Rails 3.2, pude obter meu middleware TrafficCop Carregando colocando -o em app/middleware/traffic_cop.rb, assim como o @mikejarema descreveu. Eu então adicionei esta linha ao meu config/application.rb, conforme instruído:

config.middleware.use TrafficCop

No entanto, após o início do aplicativo, continuei recebendo este erro:

uninitialized constant MyApp::Application::TrafficCop

Especificar explicitamente o espaço para nome das raizs também não ajudou:

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

Por algum motivo (que ainda não descobri), neste momento do ciclo de vida do Rails, app/middleware não foi incluído nos caminhos de carga. Se eu removesse o config.middleware.use linha e corri o console, eu poderia acessar o TrafficCop constante sem nenhum problema. Mas não conseguiu encontrá -lo em app/middleware no momento da configuração.

Eu consertei isso envolvendo o nome da classe de middleware em citações, como assim:

config.middleware.use "TrafficCop"

Dessa forma, eu evitaria o uninitialized constant erro, já que o Rails não está tentando encontrar o TrafficCop classe ainda. Mas, quando começa a construir a pilha de middleware, consta -se a string. Por esta hora, app/middleware está nos caminhos de carga e, portanto, a classe será carregada corretamente.

Para Rails 3:

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

Não estou ciente de uma convenção, mas por que não colocá -la no /lib diretório? Os arquivos lá são carregados automaticamente por trilhos.

Você pode criar um inicializador que requer os arquivos necessários e, em seguida, deixe os arquivos onde desejar.

De acordo com isto Os inicializadores são executados antes que o middleware do rack seja carregado.

A solução de trabalho que tenho até agora é mover o middleware exige config/middleware.rb e exigindo esse arquivo em environment.rb, reduzindo -o a um único requerido com o qual possa viver.

Eu ainda gostaria de saber como outras pessoas resolveram esse problema aparentemente básico de adicionar middleware aos trilhos.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top