2014-07-03 33 views
14

Jest to trudne do wyjaśnienia. Mam moduł w innej przestrzeni nazw modułu tak:Szyny niezdolne do autoloadowania stałej z pliku, mimo że zdefiniowano go w tym pliku.

# app/models/points/calculator.rb 
module Points 
    module Calculator 
    def self.included(base) 
     base.send(:include, CommonMethods) 
     base.send(:include, "Points::Calculator::#{base}Methods".constantize) 
    end 
    end 
end 

Więc w innych klasach wszystko co musisz zrobić, to:

class User 
    include Points::Calculator 
end 

Mam ten katalog określony w environment.rb być autoloadable ... (chociaż myślę, że szyny powtarzają się przez modele ...)

config.autoload_paths += Dir[ Rails.root.join('app', 'models', "points") ] 

W środowisku rozwojowym wszystko działa dobrze. Podczas uruchamiania testów (i env produkcja), pojawia się następujący błąd:

Unable to autoload constant Points::Calculator, expected /Users/pete/work/recognize/app/models/points/calculator.rb to define it (LoadError) 

I rzeczywiście po radę, żeby rozwiązać ten problem: Stop Rails from unloading a module in development mode jawnie wymagając calculator.rb w environment.rb.

Dlaczego tak się dzieje?

Utknąłem niektóre dane wyjściowe debugowania w pliku dependencies.rb ActiveSupport i zauważyłem, że plik ten jest wymagany dwukrotnie. Za pierwszym razem, gdy jest to wymagane, widzę, że stała jest rzeczywiście załadowana.

Ale po raz drugi wymagana stała została rozładowana tak długo, jak Railsy mogą powiedzieć, ale kiedy faktyczne wymaganie jest wywoływane, ruby ​​zwraca false, ponieważ ruby ​​wie, że jest już to wymagane. Następnie Railsy zgłaszają błąd "nie może się automatycznie ładować", ponieważ stała wciąż nie jest obecna, a rubin nie "wymaga ponownego" tego pliku.

Czy ktoś może rzucić światło na to, dlaczego tak się dzieje?

+0

Czy usuwanie punktów z utraconych ścieżek, które można samodzielnie ładować, pomaga? To nie powinno być konieczne –

+0

Tak, próbowałem go z i bez w ścieżce autoload. Taki sam problem. –

+0

Wydaje się, że masz ten sam problem. Bardzo denerwujące, że muszę wymagać zajęć, ponieważ mam około 30 takich zajęć. – Kohanz

Odpowiedz

0

Calculator powinny być klasa być ładowane automatycznie prawidłowo

module Points 
    class Calculator 
    ... 
    end 
end 
+0

Przepraszam, opisałem to źle, jest to moduł w module ... Zaktualizowałem powyższy opis, aby był dokładniejszy ... czy fakt, że jego moduł wpływa na automatyczne ładowanie? –

+0

W takim przypadku zalecam umieszczenie pliku w katalogu 'lib' zamiast' app/models' – infused

+1

lib jest dla bibliotek nie należących do aplikacji, stąd też umieszczam tę aplikację /. Mogę jednak zauważyć argumenty przemawiające za umieszczeniem tego w aplikacji/lib lub może w app/concern lub app/models/concerns directory –

7

Szyny zwiększa stałą mechanizmu wyszukiwania z rubinem.

Stała wyszukiwanie w Ruby:

podobne do method missing, A Module#constant-missing jest wywoływana gdy odniesienie do stałej nie zostać rozwiązane. Kiedy mówimy o stałą w danym zakresie leksykalnym, że stała jest poszukiwany w:

Each entry in Module.nesting 
Each entry in Module.nesting.first.ancestors 
Each entry in Object.ancestors if Module.nesting.first is nil or a module. 

Kiedy odnosimy się do stałej, Ruby najpierw próbuje go znaleźć według tego wbudowaną zasad odnośników.

Kiedy ruby ​​nie znajdzie ... szyny kopnięć w, a przy użyciu its own lookup convention oraz jego wiedzę o którym stałe zostały już załadowane (Ruby) Szyny nadpisuje Module#const_missing załadować brakujące stałe bez konieczności wyraźnego wymagają wywoływania przez programistę.

Sama konwencja wyszukiwania?

Autoloadowanie kontrastujące Ruby (wymagające wcześniejszego określenia położenia stałej autoloaded) szyny zgodnie z konwencją, która mapuje stałe do nazw plików.

Points::Calculator # =>points/calculator.rb 

teraz na stałe punkty :: Kalkulator szyn przeszukuje tę ścieżkę (czyli „punktów/calculator.rb”) w ścieżkach autoLoad, zdefiniowany przez konfigurację autoload_paths.

W tym przypadku szyny szukały ścieżek do plików points/calculator w swoich ścieżkach automatycznie ładowanych, ale nie znalazły pliku, a tym samym wyświetlany jest ten błąd/ostrzeżenie.

Ta odpowiedź jest abstraktem z tego Urbanautomation blog.

+5

Rzeczywiście, widziałem ten post i dziękuję za wyjaśnienia. Ale plik istnieje i jest ładowany poprawnie raz, ale jak wspomniano powyżej, widzę, że wymaga tego dwa razy, a na drugim, stała została rozładowana. Nie jestem pewien, w jaki sposób twoje wyjaśnienie odnosi się do tego faktu. –

+3

Rozwiązałeś to? – Joe