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.