Wiem, że minęło dużo czasu, odkąd zadano to pytanie po raz pierwszy, ale mam dodatkową odpowiedź, którą chcę się podzielić.
Mam kilka aplikacji Ruby, które zostały opracowane przez innego programistę przez kilka lat i ponownie używają tych samych klas w różnych aplikacjach, chociaż mogą uzyskiwać dostęp do tej samej bazy danych. Ponieważ narusza to zasadę DRY, zdecydowałem się utworzyć bibliotekę klas, która będzie współdzielona przez wszystkie aplikacje Rubiego. Mógłbym umieścić go w głównej bibliotece Ruby, ale to ukryłoby niestandardowy kod we wspólnej bazie kodu, czego nie chciałem robić.
Wystąpił problem polegający na konflikcie nazw między już zdefiniowaną nazwą „profile.rb” a klasą, której używałem. Ten konflikt nie był problemem, dopóki nie spróbowałem stworzyć wspólnej biblioteki kodu. Zwykle Ruby szuka najpierw lokalizacji aplikacji, a następnie przechodzi do lokalizacji $ LOAD_PATH.
Plik application_controller.rb nie mógł znaleźć klasy, którą utworzyłem, i zgłosił błąd do oryginalnej definicji, ponieważ nie jest to klasa. Ponieważ usunąłem definicję klasy z sekcji aplikacji / modeli aplikacji, Ruby nie mógł jej tam znaleźć i szukał jej w ścieżkach Rubiego.
Tak więc zmodyfikowałem zmienną $ LOAD_PATH, aby zawierała ścieżkę do katalogu biblioteki, którego używałem. Można to zrobić w pliku environment.rb w czasie inicjalizacji.
Nawet po dodaniu nowego katalogu do ścieżki wyszukiwania, Ruby zgłaszał błąd, ponieważ najpierw pobierał plik zdefiniowany przez system. Ścieżka wyszukiwania w zmiennej $ LOAD_PATH preferencyjnie przeszukuje najpierw ścieżki Rubiego.
Musiałem więc zmienić kolejność wyszukiwania, aby Ruby znalazł klasę w mojej wspólnej bibliotece, zanim przeszukał wbudowane biblioteki.
Ten kod zrobił to w pliku environment.rb:
Rails::Initializer.run do |config|
* * * * *
path = []
path.concat($LOAD_PATH)
$LOAD_PATH.clear
$LOAD_PATH << 'C:\web\common\lib'
$LOAD_PATH << 'C:\web\common'
$LOAD_PATH.concat(path)
* * * * *
end
Nie sądzę, abyś mógł użyć żadnej z zaawansowanych konstrukcji kodowania podanych wcześniej na tym poziomie, ale działa dobrze, jeśli chcesz skonfigurować coś w czasie inicjalizacji w swojej aplikacji. Musisz zachować oryginalną kolejność oryginalnej zmiennej $ LOAD_PATH po jej ponownym dodaniu do nowej zmiennej, w przeciwnym razie niektóre główne klasy Rubiego zostaną utracone.
W pliku application_controller.rb po prostu używam pliku
require 'profile'
require 'etc' #etc
a to ładuje niestandardowe pliki bibliotek dla całej aplikacji, tj. nie muszę używać poleceń wymagających w każdym kontrolerze.
Dla mnie było to rozwiązanie, którego szukałem i pomyślałem, że dodam je do tej odpowiedzi, aby przekazać informacje.
File.expand_path(File.dirname(__FILE__)).tap {|pwd| $LOAD_PATH.unshift(pwd) unless $LOAD_PATH.include?(pwd)}