Como a versão mais recente do Rails 3 não carrega mais módulos e classes da lib, qual seria a melhor maneira de carregá-los?
No github:
A few changes were done in this commit: Do not autoload code in *lib* for applications (now you need to explicitly require them). This makes an application behave closer to an engine (code in lib is still autoloaded for plugins);
ruby-on-rails
class
module
autoload
ruby-on-rails-3
Vincent
fonte
fonte
app/lib
.Fonte: Rails 3 Dica rápida: carregamento automático do diretório lib, incluindo todos os subdiretórios, evite carregamento lento
Lembre-se de que os arquivos contidos na pasta lib são carregados apenas quando o servidor é iniciado. Se você deseja o conforto de carregar automaticamente esses arquivos, leia: Rails 3 Dica rápida: recarrega automaticamente as pastas lib no modo de desenvolvimento . Esteja ciente de que isso não se destina a um ambiente de produção, pois a recarga permanente diminui a velocidade da máquina.
fonte
A mágica de carregar coisas automaticamente
Eu acho que a opção de controlar as pastas das quais o material de carregamento automático é realizado foi suficientemente abordada em outras respostas. No entanto, caso outra pessoa esteja tendo problemas com o carregamento de itens, apesar de os caminhos de carregamento automático terem sido modificados conforme necessário, essa resposta tenta explicar qual é a mágica por trás desse item de carregamento automático.
Portanto, quando se trata de carregar coisas de subdiretórios, há uma pegadinha ou uma convenção que você deve estar ciente. Às vezes, a magia Ruby / Rails (desta vez principalmente Rails) pode dificultar a compreensão de por que algo está acontecendo. Qualquer módulo declarado nos caminhos de carregamento automático será carregado apenas se o nome do módulo corresponder ao nome do diretório pai. Portanto, caso você tente colocar
lib/my_stuff/bar.rb
algo como:Não será carregado automaticamente. Então, novamente, se você mudar o nome do dir pai para
foo
hospedagem, assim, o seu módulo no caminho:lib/foo/bar.rb
. Estará lá para você. Outra opção é nomear o arquivo que você deseja carregar automaticamente pelo nome do módulo. Obviamente, só pode haver um arquivo com esse nome. Caso você precise dividir suas coisas em muitos arquivos, é claro que você poderia usar esse arquivo para exigir outros arquivos, mas eu não recomendo, porque quando no modo de desenvolvimento e você modifica esses outros arquivos, o Rails não consegue automagicamente recarregue-os para você. Mas se você realmente deseja, pode ter um arquivo com o nome do módulo que especifica os arquivos reais necessários para usar o módulo. Então você pode ter dois arquivos:lib/my_stuff/bar.rb
elib/my_stuff/foo.rb
sendo o primeiro o mesmo que acima e o último contendo uma única linha:require "bar"
e isso funcionaria da mesma forma.PS Sinto-me compelido a acrescentar mais uma coisa importante. Ultimamente, sempre que eu quero ter algo no diretório lib que precisa ser carregado automaticamente, eu tendem a começar a pensar que se isso é algo que eu estou realmente desenvolvendo especificamente para este projeto (que geralmente é, pode ser que algum dia se transformar em um trecho de código "estático" usado em muitos projetos ou em um sub-módulo git, etc. nesse caso, ele definitivamente deve estar na pasta lib) e talvez seu lugar não esteja na pasta lib. Talvez deva estar em uma subpasta na pasta do aplicativo · Sinto que essa é a nova maneira de fazer trilhos. Obviamente, a mesma mágica está no trabalho, onde quer que você carregue automaticamente os caminhos em que coloca suas coisas, por isso é bom para essas coisas. Enfim, este é apenas o meu pensamento sobre o assunto. Você é livre para discordar. :)
ATUALIZAÇÃO: Sobre o tipo de mágica ..
Como severin apontou em seu comentário, o núcleo "mecanismo de carregamento automático de um módulo" certamente faz parte do Ruby, mas o material dos caminhos de carregamento automático não é. Você não precisa do Rails para fazer
autoload :Foo, File.join(Rails.root, "lib", "my_stuff", "bar")
. E quando você tentaria fazer referência ao módulo Foo pela primeira vez, ele seria carregado para você. No entanto, o que o Rails faz é fornecer uma maneira de tentar carregar coisas automaticamente de pastas registradas e isso foi implementado de tal maneira que ele precisa assumir algo sobre as convenções de nomenclatura. Se não tivesse sido implementado dessa maneira, toda vez que você fizer referência a algo que não está carregado no momento, precisará passar por todos os arquivos em todas as pastas de carregamento automático e verificar se algum deles contém o que você estava tentando fazer referência. Por sua vez, isso derrotaria a idéia de carregamento automático e carregamento automático. No entanto, com essas convenções em vigor, é possível deduzir do módulo / classe sua tentativa de carregar onde isso pode ser definido e apenas carregá-lo.fonte
Aviso: se você deseja carregar o 'patch de macaco' ou 'classe aberta' da pasta 'lib', não use a abordagem 'autoload' !!!
Abordagem " config.autoload_paths ": funciona apenas se você estiver carregando uma classe que foi definida apenas em UM local. Se alguma classe já foi definida em outro lugar, não será possível carregá-la novamente por essa abordagem.
Abordagem " config / initializer / load_rb_file.rb ": sempre funciona! qualquer que seja a classe de destino, seja uma nova classe ou uma "classe aberta" ou "patch de macaco" para a classe existente, ela sempre funciona!
Para obter mais detalhes, consulte: https://stackoverflow.com/a/6797707/445908
fonte
Muito parecido, mas acho que isso é um pouco mais elegante:
fonte
No meu caso, eu estava tentando simplesmente carregar um arquivo diretamente sob o diretório lib.
Dentro do application.rb ...
não estava funcionando, mesmo no console e quando tentei
e trilhos carrega o arquivo perfeitamente.
Eu ainda sou muito noob e não sei por que isso funciona, mas funciona. Se alguém gostaria de me explicar, eu apreciaria: espero que isso ajude alguém de qualquer maneira.
fonte
Eu tive o mesmo problema. Aqui está como eu resolvi isso. A solução carrega o diretório lib e todos os subdiretórios (não apenas o direto). Claro que você pode usar isso para todos os diretórios.
fonte
Expected lib/bar/foo.rb to define constant Foo
se tentar carregar o lib / foo.rb consultando o Foo constante.config.autoload_paths não funciona para mim. Eu resolvo de outra maneira
fonte
Se apenas determinados arquivos precisarem acessar os módulos na lib, basta adicionar uma instrução require aos arquivos que precisam. Por exemplo, se um modelo precisar acessar um módulo, adicione:
na parte superior do arquivo model.rb.
fonte
require
dentro de um aplicativo Rails, porque impede oActiveSupport::Dependencies
carregamento [des] desse código corretamente. Em vez disso, você deve usarconfig.autoload_paths
como a resposta acima e incluir / estender conforme necessário.require
de nenhum lugar do aplicativo Rails? Em uma tarefa rake Atualmente estourequire
ing einclude
ing um módulo que vive emlib/
. Eu não deveria estar fazendo isso?require
seulib/
código (por exemplo, esta postagem no blog , esta resposta do SO ). Ainda não tenho certeza sobre a coisa toda. Você pode fornecer mais evidências por trás da reivindicação por não usarrequire
?Soletre o nome do arquivo corretamente.
Seriamente. Eu lutei com uma classe por uma hora porque a classe era Governance :: ArchitectureBoard e o arquivo estava em lib / governança / architecture_baord.rb (O e A transpostos no "quadro")
Parece óbvio em retrospecto, mas foi o diabo que o localizou. Se a classe não estiver definida no arquivo em que o Rails espera que ela seja baseada na seleção do nome da classe, ela simplesmente não a encontrará.
fonte
A partir de
Rails 5
, recomenda-se colocar a pasta lib no diretório do aplicativo ou em vez criar outros espaços nome significativo para a pasta comoservices
,presenters
,features
etc e colocá-lo no diretório app para carregamento automático por trilhos.Por favor, verifique este link de discussão do GitHub também.
fonte
Existem várias razões pelas quais você pode ter problemas para carregar a partir da lib - consulte aqui para obter detalhes - http://www.williambharding.com/blog/technology/rails-3-autoload-modules-and-classes-in-production/
fonte