2017-10-18 27 views
6

Oto a brand new Rails 5.1.4 app, z modelem i kilkoma trasami i kontrolerami.Automatyczne ładowanie szyny/stała rozdzielczość tworzy moduły widmowe

przestrzeni nazw kontroler odwołuje się do topowy model Level:

class AdminArea::WelcomeController < ApplicationController 
    def index 
    @user = User.new(name: 'Sergio') 
    end 
end 

tej pory tak dobrze. Możesz sprawdzić mastera, przejść do http://localhost:3000/admin_area/welcome i zobaczyć, jak działa.

ALE jeśli mamy were to add an empty directory app/presenters/admin_area/user/ *, wtedy sprawy stają się dziwne. Nagle, User w tym kontrolerze nie jest moim modelem, ale nieistniejącym modułem!

NoMethodError (undefined method `new' for AdminArea::User:Module): 

app/controllers/admin_area/welcome_controller.rb:3:in `index' 

Oczywiście ten moduł nie ma żadnych [niewbudowanych] metod i nie można go przypiąć do pliku źródłowego na dysku.

Pytanie: dlaczego dodanie pustego katalogu powoduje szyny do modułu tajemniczo wyczarować z powietrza zamiast poprawnie rozwiązać nazwę User do mojego modelu?


* faktycznie, jeśli sprawdzeniu, że oddział jak jest, dostaniesz inny błąd.

NameError (niezainicjowany stała AdminArea :: WelcomeController :: User)

ponieważ git nie pozwolił mi popełnić pusty katalog, więc dodałem plik .keep tam. Ale jak tylko usuniesz ten plik, otrzymasz opisane powyżej zachowanie.

+0

Możliwy duplikat [Rails 4: organizują modeli szyn sub ścieżki bez przestrzeni nazw modeli] (https://stackoverflow.com/questions/18934115/rails-4-organize-rails-models-in-sub -path-without-namespacing-models) – jon1467

+0

@ jon1467: nie, nie duplikat tego. Chyba że czegoś mi brakuje. –

+0

Ach przepraszam, myślę, że błędnie przeczytałem twoje pytanie, pytając, jak umieścić swój model użytkownika w katalogu 'prezenterów'. Mój błąd. – jon1467

Odpowiedz

5

Jest to konsekwencją ciągłego wyszukiwania ruby ​​i tego, jak Rails rozwiązuje automatyczne ładowanie.

Stała w kontrolerze to tak zwana "relative reference", co oznacza, że ​​powinna zostać rozwiązana względem przestrzeni nazw, w której występuje. Do tego stała, istnieją trzy możliwe warianty, gdzie stała mogą być zdefiniowane:

AdminArea::WelcomeController::User 
AdminArea::User 
User 

Szyny autoloading Mapy te stałe na nazwy plików i iteruje się autoload_path s, aby wybrać plik stałą gdzie jest zdefiniowana. Np .:

app/assets/admin_area/welcome_controller/user.rb 
app/assets/admin_area/welcome_controller/user 
app/channels/admin_area/welcome_controller/user.rb 
... 
app/assets/admin_area/user.rb 
app/assets/admin_area/user 
... 
app/assets/user.rb 
... 
app/models/user.rb #=> here it is! 

Po dodaniu folderu admin_area/user do katalogu prezenterów, jesteś skutecznie definiowania taka stała. Modules in Rails are automagically created, tak więc nie musisz tworzyć plików, w których definiujesz te moduły, które działają tylko jako przestrzenie nazw.

Kiedy dodany folder, folder pojawił się w odnośnika szyn:

... 
app/assets/admin_area/user.rb 
app/assets/admin_area/user 
... 
app/presenters/admin_area/user #=> Here Rails finds the folder 

Szyny i uchwala User odwołać do tego modułu.

Jednak jest to dość łatwe do naprawienia, Jeśli chcesz User stałej, który jest używany w ciągu AdminArea nazw odwołać stałą najwyższego poziomu (a nie modułu AdminArea::User), należy zmienić „odwołanie względne” w produkt bezwzględne odniesienie poprzedzające stałą z ::.

@user = ::User.new(name: 'Sergio') 
+0

Jedyny brakujący element, jak sądzę, jest linkiem do kodu, który automagicznie tworzy moduły. –

+1

Idź tam http://guides.rubyonrails.org/autoloading_and_reloading_constants.html#automatic-modules :) "Jeśli autoload_paths ma plik o nazwie admin.rb Rails ma zamiar go załadować, ale jeśli nie ma takiego pliku i znajduje się katalog o nazwie admin, Rails tworzy pusty moduł i przypisuje go do stałej Admin w locie. " –

+0

To wszystko, dzięki! Przyznam nagrodę jak tylko mi pozwoli :) –