Najlepszy sposób na załadowanie modułu / klasy z folderu lib w Rails 3?

Ponieważ najnowsze wydanie Rails 3 nie powoduje już automatycznego ładowania modułów i klas z 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);
Author: Vincent, 2010-07-28

12 answers

Od Rails 2.3.9 , w config/application.rb istnieje ustawienie, w którym możesz określić katalogi zawierające pliki, które chcesz autoładować.

Z aplikacji.rb:

# Custom directories with classes and modules you want to be autoloadable.
# config.autoload_paths += %W(#{config.root}/extras)
 248
Author: Slobodan Kovacevic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-18 21:53:21
# Autoload lib/ folder including all subdirectories
config.autoload_paths += Dir["#{config.root}/lib/**/"]

Source: Rails 3 Quicktip: Autoload katalog lib zawierający wszystkie podkatalogi, unikaj leniwego ładowania

Należy pamiętać, że pliki znajdujące się w folderze lib są ładowane dopiero po uruchomieniu serwera. Jeśli chcesz mieć możliwość automatycznego załadowania tych plików, przeczytaj: Rails 3 Quicktip: Auto reload lib folders in development mode. Należy pamiętać, że nie jest to przeznaczone dla środowiska produkcyjnego, ponieważ stałe przeładowanie spowalnia maszynę.

 195
Author: thankful,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-03 05:49:44

Magia automatycznego ładowania rzeczy]}

Myślę, że opcja kontrolująca foldery, z których odbywa się automatyczne ładowanie, została wystarczająco omówiona w innych odpowiedziach. Jednak w przypadku, gdy ktoś inny ma problemy z załadowaniem rzeczy, mimo że ścieżki automatycznego ładowania zostały zmodyfikowane zgodnie z wymaganiami, ta odpowiedź próbuje wyjaśnić, jaka jest magia tego autoładowania.

Więc jeśli chodzi o wczytywanie rzeczy z podkatalogów to jest konwencja, którą powinieneś świadomy. Czasami Magia Ruby / Rails (tym razem głównie Rails) może utrudnić zrozumienie, dlaczego coś się dzieje. Każdy moduł zadeklarowany w ścieżkach autoload zostanie załadowany tylko wtedy, gdy nazwa modułu odpowiada nazwie katalogu nadrzędnego. Więc jeśli spróbujesz umieścić w lib/my_stuff/bar.rb coś w stylu:

module Foo
  class Bar
  end
end

Nie zostanie załadowany automatycznie. Jeśli zmienisz nazwę katalogu nadrzędnego na foo, hostując swój moduł w path: lib/foo/bar.rb. Będzie tam dla Ciebie. Inną opcją jest nazwij plik, który ma być automatycznie ładowany przez nazwę modułu. Oczywiście wtedy może być tylko jeden plik o tej nazwie. W przypadku, gdy musisz podzielić swoje rzeczy na wiele plików, możesz oczywiście użyć tego jednego pliku, aby zażądać innych plików, ale nie polecam tego, ponieważ wtedy, gdy jesteś w trybie deweloperskim i modyfikujesz te inne pliki, Rails nie jest w stanie automatycznie załadować ich za Ciebie. Ale jeśli naprawdę chcesz, możesz mieć jeden plik o nazwie modułu, który następnie określa rzeczywiste pliki wymagane do użyj modułu. Więc możesz mieć dwa pliki: lib/my_stuff/bar.rb i lib/my_stuff/foo.rb i pierwszy jest taki sam jak powyżej, a drugi zawiera jedną linię: {[6] } i to będzie działać tak samo.

P. S. czuję się zmuszony do dodania jeszcze jednej ważnej rzeczy. Od niedawna, kiedy chcę mieć coś w katalogu lib, co wymaga autoloadowania, zaczynam myśleć, że jeśli jest to coś, co właściwie rozwijam specjalnie dla tego projektu (co zwykle jest, może pewnego dnia przekształcić się w" statyczny " fragment kodu używany w wielu projektach lub submodule git, itp.. w takim przypadku zdecydowanie powinien znajdować się w folderze lib) wtedy być może jego miejsce w ogóle nie znajduje się w folderze lib. Być może powinien być w podfolderze w folderze aplikacji· mam wrażenie,że jest to nowy sposób rails. Oczywiście ta sama magia działa wszędzie tam, gdzie w ścieżkach automatycznego ładowania umieszczasz swoje rzeczy, więc jest to dobre dla tych rzeczy. W każdym razie, to tylko moje przemyślenia na ten temat. Jesteś wolno się nie zgadzać. :)


Aktualizacja: o rodzaju magii..

Jak zauważył severin w swoim komentarzu, rdzeń "autoload a module mechanism" z pewnością jest częścią Rubiego, ale ścieżki autoload nie są. nie potrzebujesz Railsów do tego autoload :Foo, File.join(Rails.root, "lib", "my_stuff", "bar"). A kiedy spróbujesz odwołać się do modułu Foo po raz pierwszy, zostanie on załadowany dla Ciebie. Jednak to, co robi Rails, daje nam sposób na automatyczne ładowanie rzeczy z zarejestrowanych folderów i zostało to zaimplementowane w taki sposób, że musi zakładać coś na temat konwencji nazewnictwa. Gdyby nie zostało to zaimplementowane w ten sposób, to za każdym razem, gdy odwołujesz się do czegoś, co nie jest aktualnie załadowane, musiałoby przejść przez wszystkie pliki we wszystkich folderach autoload i sprawdzić, czy któryś z nich zawiera to, co próbujesz odwołać. To z kolei zniweczyłoby ideę automatycznego ładowania i automatycznego ładowania. Jednak z tymi konwencjami można odliczyć od modułu / klasy Twoje próbuję załadować, gdzie można to zdefiniować i po prostu załadować.

 80
Author: Timo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-05 15:10:03

Uwaga: Jeśli chcesz załadować ' monkey patch 'lub' open class 'z folderu 'lib', nie używaj metody 'autoload' !!!

  • "config.autoload_paths" podejście: działa tylko wtedy, gdy ładujesz klasę zdefiniowaną tylko w jednym miejscu. Jeśli jakaś klasa została już zdefiniowana gdzie indziej, to nie można jej ponownie załadować za pomocą tego podejścia.

  • "config / initializer / load_rb_file.RB" podejście: zawsze działa! niezależnie od celu klasa jest nową klasą lub "klasą otwartą" lub "małpią łatką" dla istniejącej klasy, zawsze działa!

Aby uzyskać więcej informacji, zobacz: https://stackoverflow.com/a/6797707/445908

 40
Author: Siwei Shen申思维,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:14

Bardzo podobne, ale myślę, że to jest trochę bardziej eleganckie:

config.autoload_paths += Dir["#{config.root}/lib", "#{config.root}/lib/**/"]
 26
Author: Brian Armstrong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-02 07:46:29

W moim przypadku próbowałem po prostu załadować plik bezpośrednio pod katalog lib.

W aplikacji.rb...

require '/lib/this_file.rb' 

Nie działa, nawet w konsoli, a potem, gdy próbowałem

require './lib/this_file.rb' 

I rails ładuje plik idealnie.

Nadal jestem całkiem noobem i nie wiem, dlaczego to działa, ale działa. Gdyby ktoś chciał mi to wyjaśnić byłbym wdzięczny :D Mam nadzieję, że to i tak komuś pomoże.
 14
Author: Nick Res,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-15 01:44:20

Miałem ten sam problem. Oto jak to rozwiązałem. Rozwiązanie wczytuje katalog lib i wszystkie podkatalogi(nie tylko bezpośrednie). Oczywiście możesz użyć tego dla wszystkich katalogów.

# application.rb
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
 7
Author: hjuskewycz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-07 20:22:20

Config.autoload_paths nie działa dla mnie. Rozwiązuję to w inny sposób

Ruby on rails 3 nie powoduje automatycznego przeładowywania (autoload) kodu z folderu /lib. Rozwiązuję go umieszczając w środku ApplicationController

Dir["lib/**/*.rb"].each do |path|
  require_dependency path
end 
 5
Author: msa7,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-07 20:23:28

Jeśli tylko niektóre pliki wymagają dostępu do modułów w lib, po prostu dodaj instrukcję require do plików, które tego potrzebują. Na przykład, jeśli jeden model musi uzyskać dostęp do jednego modułu, dodaj:

require 'mymodule'

U góry Modelu.plik rb.

 4
Author: Mike Fischer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-31 01:27:15

Istnieje kilka powodów, dla których możesz mieć problemy z załadowaniem z lib-zobacz tutaj po szczegóły - http://www.williambharding.com/blog/technology/rails-3-autoload-modules-and-classes-in-production/

  • napraw ścieżkę automatycznego ładowania
  • threadsafe related
  • nazewnictwo odnoszące się
  • ...
 1
Author: Chris Kimpton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-20 10:23:33

Począwszy od Rails 5, zaleca się umieszczenie folderu lib w katalogu app lub zamiast tego utworzenie innych znaczących przestrzeni nazw dla folderu jako services , presenters, features itp. i umieść go w katalogu aplikacji do automatycznego ładowania za pomocą szyn.

Sprawdź również ten link do dyskusji na Githubie .

 1
Author: Ashik Salman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-02 11:25:20

Poprawnie Przeliteruj nazwę pliku.

Poważnie. Walczyłem z klasą przez godzinę, ponieważ klasą była Governance:: ArchitectureBoard, a plik był w lib/governance / architecture_baord.rb (transponowane O I A w "planszy")

Wydaje się oczywiste z perspektywy czasu, ale to diabeł to tropił. Jeśli klasa nie jest zdefiniowana w pliku, w którym rails oczekuje, że będzie w oparciu o wymontowanie nazwy klasy, po prostu jej nie znajdzie.

 0
Author: David Hempy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-19 16:00:55