2015-04-15 9 views
5

Data la seguente struttura di controllo:Rails portata

# application_controller.rb 
class ApplicationController < ActiveController::Base; end 

# pages_controller.rb 
class PagesController < ApplicationController; end 

# admin/application_controller.rb 
module Admin 
    class ApplicationController < ::ApplicationController; end 
end 

# admin/pages_controller.rb 
module Admin 
    class PagesController < ApplicationController; end 
end 

ci si aspetterebbe Admin::PagesController ereditare da Admin::ApplicationController e lo fa. Ma ho notato che a volte eredita da ::ApplicationController.

così ho deciso di non rischiare e ha cambiato dichiarazione di tutti i controller in /admin per indirizzare specificamente Admin::ApplicationController

# admin/pages_controller.rb 
module Admin 
    class PagesController < Admin::ApplicationController; end 
end 

Va bene che funziona, ma da quello che so che è stato corretto in primo luogo. Perché Rails talvolta eredita da un controller sbagliato?

Admin::PagesControllervolte eredita da ApplicationController invece di Admin::ApplicationController pur essendo entrambi nella stessa module Admin

+0

avevo sperimentato problema simile !!! – Hardik

risposta

4

Il problema qui è il codice modalità di sviluppo di carico rotaie: in generale codice viene caricato quando si tenta di fare qualcosa con una costante (ad es. sottoclasse da esso) e quella costante non esiste. Ciò si traduce in const_missing chiamato e rails lo utilizza per provare a caricare la classe (per una descrizione dettagliata, vedere the guide).

Se né ApplicationController né Admin :: ApplicationController esistono poi quando si accede rubino controllore pagine di amministrazione che colpirà const_missing e cercare di caricare admin/application_controller.rb

Tuttavia, se ApplicationController è già caricato poi rubino non lo farà fire const_missing poiché è perfettamente legale per una classe nel modulo admin ereditare da qualcosa al livello superiore.

La soluzione, come dici tu, è rendere esplicito ciò da cui stai ereditando. Personalmente nelle mie app uso la classe base Admin::BaseController.

+0

Si comporterebbe allo stesso modo in produzione? – firedev

+0

@Nick In produzione tutto viene caricato in anticipo quindi spero di no ma suppongo che se i file fossero caricati in un certo ordine potrebbe ancora succedere - non so se i binari cercano di evitarlo. –

1

Un'altra opzione è quella di utilizzare require_dependency per puntare Rails al file corretto:

# admin/application_controller.rb 

require_dependency 'admin/application_controller' 

module Admin 
    class PagesController < ApplicationController 
    end 
end 
+0

Immagino che in questo caso sia meglio usare un nome univoco come "AdminController" o esplicitamente come "Admin :: ApplicationController" – firedev