ActiveAdmin ist gut dokumentiert und auch ohne Verständnis der Interna gut zu benutzen. Spätestens wenn man eigene Erweiterungen schreiben möchte, muss man aber verstehen, wie die Engine funktioniert. Ein Anfang für Version 1.0.0.pre1:
Das Modul ActiveAdmin realisiert mittels class << self eine singleton-ähnliche Instanz von ActiveAdmin::Application:
module ActiveAdmin
class << self
def application
@application ||= ::ActiveAdmin::Application.new
end
Beim Setzen der Routen in der routes.rb wird automatisch load! ausgelöst:
module ActiveAdmin
class Application
def routes(rails_router)
load!
router.apply(rails_router)
end
Dieses lädt alle Dateien (üblicherweise app/admin/*) und erzeugt den Default-Namespace :admin:
def load!
files.each{ |file| load file }
namespace(default_namespace)
end
Die Admin-Dateien registrieren Ressourcen mittels ActiveAdmin.register Resource. Das Modul delegiert dies an die Application, diese an den Namespace. Hier wird eine zur Klasse passende ÀctiveAdmin::Resource erstellt, die im weiteren Kontext meist als config auftritt:
module ActiveAdmin
class Namespace
def register(resource_class, options = {}, &block)
config = find_or_build_resource(resource_class, options)
parse_registration_block(config, resource_class, &block) if block_given?
Der Block, der beim Anlegen der Ressource angegeben wurde, wird als eine Instanz von ActiveAdmin::ResourceDSL, welcher die config der Ressource zur Verfügung steht.
def parse_registration_block(config, resource_class, &block)
config.dsl = ResourceDSL.new(config, resource_class)
config.dsl.run_registration_block(&block)
end
Bei der Beschreibung einer Ressource stehen somit die Methoden von ActiveAdmin::ResourceDSL und der Oberklasse ActiveAdmin::DSL zur Verfügung:
module ActiveAdmin
class ResourceDSL < DSL
def initialize(config, resource_class)
@resource = resource_class
super(config)
end
def belongs_to(target, options = {})
def scope(*args, &block)
def permit_params(*args, &block)
def index(options = {}, &block)
Zudem bietet der ActiveAdmin::Resource unter config weitere Metainformationen:
module ActiveAdmin
class Resource
attr_reader :resource_class_name
attr_reader :member_actions
attr_reader :collection_actions
include Base
include ActionItems
include Authorization
include Controllers
include Menu
include Naming
include PagePresenters
include Pagination
include Scopes
include Includes
include ScopeTo
include Sidebars
include Routes
def resource_class
def decorator_class
def resource_table_name
def resource_column_names
def defined_actions
def find_resource(id)
Neben Ressourcen kennt ActiveAdmin noch das Konzept der Pages. Deren Initialisierung funktioniert im Wesentlichen ähnlich, nur dass hier eine spezielle ActiveAdmin::PageDSL verwendet wird und als config eine ActiveAdmin::Page dient.
Wenn möglich, werden die für eine Konfiguration möglichen Implementierungen schon bei der Initialisierung von ActiveAdmin erzeugt (etwa Methoden im Ressourcen-Controller). Von Laufzeitdaten abhängige Elemente werden meist in Konfigurationsobjekte gepackt. Diese speichern u.a. Blöcke, die dann zur Laufzeit mit den benötigten Daten ausgeführt werden können. Der Vorgang der Initialiserung ist somit abgeschlossen.