2015-02-19 6 views
5

ho organizzato alcuni dei miei modelli binari in cartelle, che sto caricamento automatico conRails modelli in sottocartelle e relazioni

config.autoload_paths += Dir[Rails.root.join('app', 'models', '{**}')] 

posso utilizzare tutti i modelli direttamente (ad esempio Image.first.file_name), ma quando cerco di accedervi attraverso le relazioni, per esempio @housing.images.each do... con has_many: images ottengo il seguente errore

Unable to autoload constant Housing::HousingImage, expected /path/app/models/housing/image.rb to define it 

Come faccio ad avere le rotaie di usare i miei modelli per i metodi di relazione?

Io corro rubino 2.2 e 4.2 rotaie

risposta

6

Rails carica automaticamente i modelli dal sottocartelle, ma si aspetta loro di avere spazio dei nomi.

/app/models/user.rb 
class User 
end 

/app/models/something/user.rb 
class Something::User 
end 

Se non namespace correttamente i modelli in sottocartelle sarà rovinare Rails autoloader e causare errori come si vede.

Inserisci questa

config.autoload_paths += Dir[Rails.root.join('app', 'models', '{**}')] 

e aggiungere il namespace adeguate per i vostri modelli e tutto funziona bene.

Si può facilmente utilizzare modelli namespace nei vostri rapporti come questo:

class User 
    has_many :photos, class_name: 'Something::Photo' 
end 

user.photos (will be instances of Something::Photo) 

Se non si desidera utilizzare il namespacing ma dividere il modelli per altri motivi, si può fare a livello superiore e utilizzare altre cartelle accanto ai modelli. Per impostazione predefinita i binari caricano tutte le cartelle nelle app, quindi puoi semplicemente creare una cartella "models2" o qualsiasi altra cosa tu voglia chiamare accanto a "models". Ciò non avrà alcun effetto sulla funzionalità del caricamento della classe rails.

Dato il tuo esempio si potrebbe poi fare:

/app 
    /controllers 
    /models 
    for all your normal models 
    /housing 
    for your "housing" models 

come non è possibile accedervi direttamente presso lo spazio dei nomi di alto livello, senza impostazioni nome_classe o qualsiasi cosa necessaria.

+1

Correggere, ma non li ho nominati, è per questo che ho aggiunto la configurazione in primo luogo. Ho anche provato l'opzione class_name con il nome della classe non namespace, ma non ha funzionato neanche. –

+1

All'interno dei modelli (o qualsiasi altra cartella di binari) è necessario attenersi alla convenzione di denominazione dei binari altrimenti questo causerà un sacco di mal di testa. In alternativa puoi dividere direttamente la cartella dei modelli (vedi la mia risposta aggiornata tra un momento) – maxigs

+0

Ok, andrò con la tua soluzione, ma penso che l'opzione class_name sulla relazione dovrebbe funzionare? Aprirò un problema su github per indagare ulteriormente. –