2015-04-15 4 views
5

die folgende Reglerstruktur Gegeben:Rails Modul Anwendungsbereich

# 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 

Man würde erwarten, Admin::PagesController von Admin::ApplicationController zu erben und es tut. Aber ich habe bemerkt, dass es manchmal von ::ApplicationController erbt.

So entschied ich es nicht zu riskieren, zu und verändern Erklärung aller Regler in /admin speziell Admin::ApplicationController

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

Okay, das funktioniert, zielen, sondern von dem, was ich weiß, dass es richtig war in erster Linie. Warum erbt Rails manchmal einen falschen Controller?

Admin::PagesControllermanchmal erbt von ApplicationController statt Admin::ApplicationController trotz beide module Admin

+0

ich ähnliches Problem erlebt hatte !!! – Hardik

Antwort

4

Das Problem hier in der gleichen zu sein, ist Schienen Entwicklungsmodus Code Laden: im allgemeinen Code geladen wird, wenn Sie versuchen, etwas mit einer Konstante zu tun (zB Unterklasse von ihm) und diese Konstante existiert nicht. Dies führt dazu, dass const_missing aufgerufen wird und Rails verwendet, um zu versuchen, die Klasse zu laden (für eine detaillierte Beschreibung siehe the guide).

Wenn weder Application noch Admin :: Application existiert dann, wenn Sie Ihren Admin-Seiten-Controller Rubin zugreifen, dass const_missing treffen und versucht Admin zu laden/application_controller.rb

Wenn jedoch bereits Application dann wird Rubin nicht geladen wird Feuer const_missing seit es vollkommen legal für eine Klasse im Admin-Modul, von etwas auf dem Toplevel erben.

Die Lösung, wie Sie sagen, ist explizit zu machen, was Sie erben. Persönlich verwende ich in meinen eigenen Apps Admin::BaseController als Basisklasse.

+0

Würde es sich in der Produktion genauso verhalten? – firedev

+0

@Nick In der Produktion ist alles im Voraus geladen, also würde ich nicht hoffen, aber ich nehme an, wenn die Dateien in einer bestimmten Reihenfolge geladen wurden, könnte es immer noch passieren - ich weiß nicht, ob rails versucht, dies zu vermeiden. –

1

Eine weitere Option ist require_dependency zu verwenden Rails auf die richtige Datei zu verweisen:

# admin/application_controller.rb 

require_dependency 'admin/application_controller' 

module Admin 
    class PagesController < ApplicationController 
    end 
end 
+0

Ich denke, in diesem Fall ist es besser, einen eindeutigen Namen wie 'AdminController' zu verwenden oder explizit einen Bereich wie' Admin :: ApplicationController' anzugeben – firedev

Verwandte Themen