Ponieważ najnowsze wydanie Rails 3 nie obsługuje już modułów i klas z biblioteki lib, jaki byłby najlepszy sposób na ich załadowanie?
Z 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);
app/lib
.Źródło: Rails 3 Skrócona wskazówka: automatycznie ładuj katalog lib zawierający wszystkie podkatalogi, unikaj leniwego ładowania
Pamiętaj, że pliki zawarte w folderze lib są ładowane tylko podczas uruchamiania serwera. Jeśli chcesz komfortowo automatycznie ładować te pliki, przeczytaj: Rails 3 Quicktip: Automatyczne ładowanie folderów lib w trybie programowania . Należy pamiętać, że nie jest to przeznaczone dla środowiska produkcyjnego, ponieważ stałe przeładowanie spowalnia maszynę.
źródło
Magia automatycznego ładowania rzeczy
Myślę, że opcja kontrolowania folderów, z których odbywa się automatyczne ładowanie, została wystarczająco opisana w innych odpowiedziach. Jednak w przypadku, gdy ktoś inny ma problemy z załadowaniem rzeczy, mimo że zmodyfikowano ich ścieżki automatycznego ładowania zgodnie z wymaganiami, odpowiedź ta próbuje wyjaśnić, na czym polega magia tego ładowania automatycznego.
Więc jeśli chodzi o ładowanie rzeczy z podkatalogów, musisz mieć gotcha lub konwencję, o której powinieneś wiedzieć. Czasami magia Ruby / Rails (tym razem głównie Rails) może utrudnić zrozumienie, dlaczego coś się dzieje. Każdy moduł zadeklarowany w ścieżkach automatycznego ładowania zostanie załadowany tylko wtedy, gdy nazwa modułu odpowiada nazwie katalogu nadrzędnego. Na wypadek, gdybyś spróbował wprowadzić
lib/my_stuff/bar.rb
coś takiego:Nie zostanie załadowany automatycznie. Potem znowu, jeśli zmiana nazwy nadrzędnej dir aby
foo
w ten sposób gospodarzem modułu w ścieżce:lib/foo/bar.rb
. Będzie tam dla ciebie. Inną opcją jest nadanie nazwy pliku, który chcesz automatycznie załadować, według nazwy modułu. Oczywiście wtedy może istnieć tylko jeden plik o tej nazwie. Jeśli chcesz podzielić swoje pliki na wiele plików, możesz oczywiście użyć tego jednego pliku, aby wymagać innych plików, ale nie polecam tego, ponieważ wtedy, gdy jesteś w trybie programowania i modyfikujesz te inne pliki, Rails nie jest w stanie automagicznie przeładuj je dla ciebie. Ale jeśli naprawdę chcesz, możesz mieć jeden plik według nazwy modułu, który określa rzeczywiste pliki wymagane do korzystania z modułu. Więc możesz mieć dwa pliki:lib/my_stuff/bar.rb
ilib/my_stuff/foo.rb
ten pierwszy jest taki sam jak powyżej, a drugi zawiera jedną linię:require "bar"
i to działałoby tak samo.PS Czuję się zmuszony dodać jeszcze jedną ważną rzecz. Ostatnio, kiedy chcę mieć coś w katalogu lib, który wymaga automatycznego załadowania, zaczynam myśleć, że jeśli jest to coś, co faktycznie opracowuję specjalnie dla tego projektu (co zwykle jest, może to pewnego dnia zamienia się w „statyczny” fragment kodu używany w wielu projektach lub podmoduł git itp., w którym to przypadku zdecydowanie powinien znajdować się w folderze lib), być może jego miejsce w ogóle nie znajduje się w folderze lib. Być może powinien on znajdować się w podfolderze w folderze aplikacji · Mam wrażenie, że jest to nowy sposób robienia rzeczy. Oczywiście, ta sama magia działa wszędzie tam, gdzie w tobie są ładowane ścieżki, w które wkładasz swoje rzeczy, więc dobrze jest z tymi rzeczami. W każdym razie to tylko moje przemyślenia na ten temat. Możesz się nie zgodzić. :)
AKTUALIZACJA: O rodzaju magii ..
Jak zauważył Severin w swoim komentarzu, rdzeń „autoload a module module” z pewnością jest częścią Ruby, ale ścieżki autoload nie są. Nie potrzebujesz do tego Railsów
autoload :Foo, File.join(Rails.root, "lib", "my_stuff", "bar")
. A kiedy spróbujesz po raz pierwszy odwołać się do modułu Foo, zostanie on dla Ciebie załadowany. Jednak to, co robi Rails, to sposób na automatyczne ładowanie rzeczy z zarejestrowanych folderów, co zostało zaimplementowane w taki sposób, że musi on założyć coś o konwencjach nazewnictwa. Jeśli nie został tak zaimplementowany, to za każdym razem, gdy odwołujesz się do czegoś, co nie jest aktualnie załadowane, musiałby przejść przez wszystkie pliki we wszystkich folderach automatycznego ładowania i sprawdzić, czy którykolwiek z nich zawiera to, co próbujesz odwołać. To z kolei podważyłoby ideę automatycznego ładowania i automatycznego ładowania. Jednak dzięki tym konwencjom można odjąć od modułu / klasy, którą próbujesz załadować tam, gdzie można to zdefiniować, i po prostu załadować.źródło
Ostrzeżenie: jeśli chcesz załadować „łatkę małpy” lub „klasę otwartą” z folderu „lib”, nie używaj podejścia „autoload” !!!
Podejście „ config.autoload_paths ”: działa tylko wtedy, gdy ładujesz klasę zdefiniowaną tylko w JEDNYM miejscu. Jeśli jakaś klasa została już zdefiniowana gdzieś indziej, nie można załadować jej ponownie dzięki temu podejściu.
Podejście „ config / initializer / load_rb_file.rb ”: zawsze działa! cokolwiek klasa docelowa jest nową klasą lub „klasą otwartą” lub „małpą łatką” dla istniejących klas, zawsze działa!
Aby uzyskać więcej informacji, zobacz: https://stackoverflow.com/a/6797707/445908
źródło
Bardzo podobne, ale myślę, że jest to trochę bardziej eleganckie:
źródło
W moim przypadku próbowałem po prostu załadować plik bezpośrednio do katalogu lib.
W ramach application.rb ...
nie działał, nawet w konsoli, a potem, kiedy próbowałem
a szyny ładują plik idealnie.
Nadal jestem dość noob i nie jestem pewien, dlaczego to działa, ale działa. Jeśli ktoś chciałby mi to wyjaśnić, byłbym wdzięczny: mam nadzieję, że to komuś pomoże.
źródło
Miałem ten sam problem. Oto jak to rozwiązałem. Rozwiązanie ładuje katalog lib i wszystkie podkatalogi (nie tylko bezpośrednie). Oczywiście możesz użyć tego dla wszystkich katalogów.
źródło
Expected lib/bar/foo.rb to define constant Foo
wystąpią mylące błędy, takie jak próba załadowania lib / foo.rb poprzez odwołanie się do Foo stały.config.autoload_paths nie działa dla mnie. Rozwiązuję to w inny sposób
źródło
Jeśli tylko niektóre pliki potrzebują dostępu do modułów w bibliotece lib, wystarczy dodać instrukcję wymagającą do plików, które tego potrzebują. Na przykład jeśli jeden model wymaga dostępu do jednego modułu, dodaj:
u góry pliku model.rb.
źródło
require
w aplikacji railsowej, ponieważ uniemożliwia onaActiveSupport::Dependencies
prawidłowe [rozładowanie] tego kodu. Zamiast tego należy użyćconfig.autoload_paths
powyższej odpowiedzi, a następnie dołączyć / rozszerzyć zgodnie z wymaganiami.require
nigdzie w aplikacji Rails? W zadaniu natarcia Jestem obecnierequire
-ing iinclude
-ing moduł, który mieszka wlib/
. Nie powinienem tego robić?require
twojegolib/
kodu (np. ten post na blogu , ta odpowiedź SO ). Nadal nie jestem pewien co do tego. Czy możesz podać więcej dowodów uzasadniających roszczenie za nieużywanierequire
?Przeliteruj nazwę pliku poprawnie.
Poważnie. Walczyłem z klasą przez godzinę, ponieważ klasą była Governance :: ArchitectureBoard, a plik znajdował się w lib / governance / architecture_baord.rb (transponowane O i A w „tablicy”)
Z perspektywy czasu wydaje się to oczywiste, ale diabeł go śledził. Jeśli klasa nie jest zdefiniowana w pliku, w którym Rails oczekuje, że będzie w oparciu o mungowanie nazwy klasy, po prostu jej nie znajdzie.
źródło
Na dzień
Rails 5
, zaleca się umieścić w folderze lib w katalogu aplikacji lub zamiast tworzyć inne przestrzenie znaczącą nazwę dla folderu jakoservices
,presenters
,features
etc i umieścić go w katalogu aplikacji do automatycznego załadunku przez szyny.Sprawdź również ten link do dyskusji w serwisie GitHub .
źródło
Jest kilka powodów, dla których możesz mieć problemy z ładowaniem z lib - zobacz tutaj, aby uzyskać szczegółowe informacje - http://www.williambharding.com/blog/technology/rails-3-autoload-modules-and-classes-in-production/
źródło