Używam następującego wiersza w inicjalizatorze, aby automatycznie załadować kod w moim /lib
katalogu podczas programowania:
config / initializers / custom.rb:
RELOAD_LIBS = Dir[Rails.root + 'lib/**/*.rb'] if Rails.env.development?
(z podręcznika Rails 3: Automatyczne ładowanie folderów lib w trybie programowania )
Działa świetnie, ale jest zbyt nieefektywny w produkcji - Zamiast ładować biblioteki lib na każde żądanie, chcę je załadować przy uruchomieniu. Ten sam blog ma inny artykuł opisujący, jak to zrobić:
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/**/"]
Jednak po przejściu na to, nawet w fazie rozwoju, dostaję NoMethodErrors, gdy próbuję użyć funkcji lib.
Przykład jednego z moich plików 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
Wywołanie Time.milli_stamp
spowoduje zgłoszenie NoMethodError
Zdaję sobie sprawę, że inni odpowiedzieli na podobne pytania dotyczące SO, ale wszystkie wydają się mieć do czynienia z konwencjami nazewnictwa i innymi zagadnieniami, o które nie musiałem się wcześniej martwić - Moje klasy lib już działały przy ładowaniu na żądanie, po prostu chcę to zmienić do per- startowego załadunku. Jak to zrobić?
Odpowiedzi:
Myślę, że to może rozwiązać twój problem:
w config / application.rb :
i zachowaj właściwą konwencję nazewnictwa w lib .
w lib / foo.rb :
w lib / foo / bar.rb :
jeśli naprawdę chcesz zrobić kilka łat małp w pliku, takich jak lib / extensions.rb , możesz ręcznie tego wymagać:
w config / initializers / requ.rb :
PS
Rails 3 Moduły / klasy autoloadu autorstwa Billa Hardinga.
I żeby zrozumieć, co dokładnie Rails robi z automatycznym ładowaniem?
przeczytaj autoloadowanie Railsów - jak to działa, a kiedy nie - Simon Coffey.
źródło
config.eager_load_paths << Rails.root.join('lib')
. Ma to jednak poważną wadę, ponieważ powodujeeager_load_paths
obciążenie również wszystkich zadań. Myślę, że rozwiązanie Lulalala jest lepsze. Oto post na blogu z dalszymiChociaż to nie odpowiada bezpośrednio na pytanie, ale myślę, że to dobra alternatywa, aby całkowicie uniknąć pytania.
Aby uniknąć wszystkich
autoload_paths
lubeager_load_paths
kłopotów, stworzyć „lib” lub „Różne” katalog w katalogu „APP”. Umieść kody w normalny sposób, a Railsy załadują pliki tak, jak ładują (i ponownie ładują) modele plików.źródło
app
, muszę to zrobić ręcznie ...... lub umieścić go w ścieżce automatycznego ładowania.app/views
katalogu, który nie został dodany; a raczej zostaje wyraźnie usunięty.lib
jest przeznaczony do kodu, który można zastosować do wielu projektów i ewentualnie wyodrębnić do klejnotu. Jeśli nie, utwórz bardziej odpowiedni folder podczas wyszukiwania aplikacji jakoservices/
lubpresenters/
nawet podkatalogi tych.To może pomóc komuś jak ja, który znajdzie tę odpowiedź, szukając rozwiązań, w jaki sposób Railsy radzą sobie z ładowaniem klasy ... Stwierdziłem, że musiałem zdefiniować,
module
czyja nazwa odpowiednio pasowała do mojej nazwy pliku, zamiast definiować klasę:W pliku lib / development_mail_interceptor.rb (Tak, używam kodu z Railscast :))
działa, ale nie ładuje się, jeśli nie umieściłem klasy w module.
źródło
LOAD_PATH/module/class.rb
(podkreślony), gdzieLOAD_PATH
znajduje się na ścieżkach ładowania używanych przez aplikację Ruby (autoload_paths w przypadku Railsów).lib
wahał się od automatycznego ładowania przez Railsy do braku automatycznego ładowania, aw ostatnich wersjach (> = Rails 3.x) nie jest automatycznie ładowany. Jakakolwiek magia sprawia, że to działa dla ciebie, nie jest zalecane. Być może jest to stary Railscast?Użyj config.to_prepare, aby załadować małpkie łatki / rozszerzenia dla każdego żądania w trybie programowania.
koniec
źródło