Eu uso a seguinte linha em um inicializador para carregar automaticamente o código no meu /lib
diretório durante o desenvolvimento:
config / inicializadores / custom.rb:
RELOAD_LIBS = Dir[Rails.root + 'lib/**/*.rb'] if Rails.env.development?
(da dica rápida do Rails 3: recarregar automaticamente as pastas lib no modo de desenvolvimento )
Funciona muito bem, mas é muito ineficiente para usar na produção. Em vez de carregar bibliotecas em cada solicitação, eu só quero carregá-las na inicialização. O mesmo blog possui outro artigo que descreve como fazer isso:
config / application.rb:
# Custom directories with classes and modules you want to be autoloadable.
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
No entanto, quando mudo para isso, mesmo em desenvolvimento, recebo NoMethodErrors ao tentar usar as funções lib.
Exemplo de um dos meus arquivos lib:
lib / extensions.rb:
Time.class_eval do
def self.milli_stamp
Time.now.strftime('%Y%m%d%H%M%S%L').to_i
end
end
A chamada Time.milli_stamp
lançará NoMethodError
Sei que outras pessoas responderam perguntas semelhantes no SO, mas todas parecem lidar com convenções de nomenclatura e outros problemas com os quais eu não precisava me preocupar antes. Minhas aulas de lib já funcionavam para carregamento por solicitação, só quero mudar para carregar por inicialização . Qual é o caminho certo para fazer isso?
Respostas:
Eu acho que isso pode resolver seu problema:
em config / application.rb :
e mantenha a convenção de nomenclatura correta na lib .
em lib / foo.rb :
em lib / foo / bar.rb :
se você realmente quiser fazer alguns patches de macaco em arquivos como lib / extensions.rb , poderá solicitá-lo manualmente:
em config / initializers / require.rb :
PS
Rails 3 módulos / classes de carregamento automático por Bill Harding.
E para entender o que o Rails faz exatamente sobre o carregamento automático?
leia o carregamento automático do Rails - como funciona e quando não funciona por Simon Coffey.
fonte
config.eager_load_paths << Rails.root.join('lib')
. No entanto, isso tem uma grande desvantagem emeager_load_paths
carregar tudo nas tarefas também. Eu acho que a solução da lulalala é melhor. Aqui está um post do blog com mais detalhes: blog.arkency.com/2014/11/…Embora isso não responda diretamente à pergunta, mas acho que é uma boa alternativa evitar a questão completamente.
Para evitar todo o
autoload_paths
oueager_load_paths
aborrecimento, criar uma "lib" ou um diretório "MISC" no diretório "app". Coloque os códigos como faria normalmente lá, e o Rails carregará arquivos da mesma forma que carregará (e recarregará) arquivos de modelo.fonte
app
, eu preciso fazê-lo manualmente ...... ou necessidade de colocá-lo no caminho autload ..app/views
diretório que não é adicionado; ou melhor, é explicitamente removido.lib
se destina a um código que pode ser aplicado a vários projetos e pode ser extraído para uma gema. Caso contrário, crie uma pasta mais apropriada na pesquisa de aplicativos comoservices/
oupresenters/
e até os subdivide.Isso pode ajudar alguém como eu que encontra essa resposta ao procurar soluções sobre como o Rails lida com o carregamento de classes ... Eu descobri que precisava definir um
module
cujo nome correspondesse ao meu nome de arquivo adequadamente, em vez de apenas definir uma classe:No arquivo lib / development_mail_interceptor.rb (Sim, estou usando o código de um Railscast :))
funciona, mas não carrega se eu não tivesse colocado a classe dentro de um módulo.
fonte
LOAD_PATH/module/class.rb
(sublinhado), ondeLOAD_PATH
está nos caminhos de carregamento usados pelo aplicativo Ruby (autoload_paths no caso do Rails).lib
flutuou de ser carregado automaticamente pelo Rails para não ser carregado automaticamente, e nas versões recentes (> = Rails 3.x) ele não é carregado automaticamente. Qualquer mágica que esteja fazendo esse trabalho para você não é recomendada. Talvez seja um Railscast antigo?Use o config.to_prepare para carregar patches / extensões de macaco para cada solicitação no modo de desenvolvimento.
fim
fonte