{"id":2767,"date":"2015-08-29T21:05:20","date_gmt":"2015-08-29T19:05:20","guid":{"rendered":"https:\/\/sgaul.de\/?p=2767"},"modified":"2015-08-30T17:21:26","modified_gmt":"2015-08-30T15:21:26","slug":"activeadmin-verstehen-von-der-application-zur-resourcedsl","status":"publish","type":"post","link":"https:\/\/sgaul.de\/2015\/08\/29\/activeadmin-verstehen-von-der-application-zur-resourcedsl\/","title":{"rendered":"ActiveAdmin verstehen: Von der Application zur ResourceDSL"},"content":{"rendered":"

ActiveAdmin<\/a> ist gut dokumentiert und auch ohne Verst\u00e4ndnis der Interna gut zu benutzen. Sp\u00e4testens wenn man eigene Erweiterungen schreiben m\u00f6chte, muss man aber verstehen, wie die Engine funktioniert. Ein Anfang f\u00fcr Version 1.0.0.pre1:<\/p>\n

Das Modul ActiveAdmin<\/code> realisiert mittels class << self<\/code> eine singleton-\u00e4hnliche Instanz von ActiveAdmin::Application<\/code>:<\/p>\n

module ActiveAdmin\r\n  class << self\r\n    def application\r\n      @application ||= ::ActiveAdmin::Application.new\r\n    end<\/pre>\n

Beim Setzen der Routen in der routes.rb<\/code> wird automatisch load!<\/code> ausgel\u00f6st:<\/p>\n

module ActiveAdmin\r\n  class Application\r\n\r\n    def routes(rails_router)\r\n      load!\r\n      router.apply(rails_router)\r\n    end<\/pre>\n

Dieses l\u00e4dt alle Dateien (\u00fcblicherweise app\/admin\/*<\/code>) und erzeugt den Default-Namespace :admin<\/code>:<\/p>\n

    def load!\r\n      files.each{ |file| load file }\r\n      namespace(default_namespace)\r\n    end<\/pre>\n

<\/p>\n

Die Admin-Dateien registrieren Ressourcen mittels ActiveAdmin.register Resource<\/code>. Das Modul delegiert dies an die Application, diese an den Namespace. Hier wird eine zur Klasse passende \u00c0ctiveAdmin::Resource<\/code> erstellt, die im weiteren Kontext meist als config<\/code> auftritt:<\/p>\n

module ActiveAdmin\r\n  class Namespace\r\n    def register(resource_class, options = {}, &block)\r\n      config = find_or_build_resource(resource_class, options)\r\n      parse_registration_block(config, resource_class, &block) if block_given?<\/pre>\n

Der Block, der beim Anlegen der Ressource angegeben wurde, wird als eine Instanz von ActiveAdmin::ResourceDSL<\/code>, welcher die config<\/code> der Ressource zur Verf\u00fcgung steht.<\/p>\n

    def parse_registration_block(config, resource_class, &block)\r\n      config.dsl = ResourceDSL.new(config, resource_class)\r\n      config.dsl.run_registration_block(&block)\r\n    end<\/pre>\n

Bei der Beschreibung einer Ressource stehen somit die Methoden von ActiveAdmin::ResourceDSL<\/code> und der Oberklasse ActiveAdmin::DSL<\/code> zur Verf\u00fcgung:<\/p>\n

module ActiveAdmin\r\n  class ResourceDSL < DSL\r\n    def initialize(config, resource_class)\r\n      @resource = resource_class\r\n      super(config)\r\n    end\r\n\r\n    def belongs_to(target, options = {})\r\n    def scope(*args, &block)\r\n    def permit_params(*args, &block)\r\n    def index(options = {}, &block)<\/pre>\n

Zudem bietet der ActiveAdmin::Resource unter config<\/code> weitere Metainformationen:<\/p>\n

module ActiveAdmin\r\n  class Resource\r\n    attr_reader :resource_class_name\r\n    attr_reader :member_actions\r\n    attr_reader :collection_actions\r\n\r\n    include Base\r\n    include ActionItems\r\n    include Authorization\r\n    include Controllers\r\n    include Menu\r\n    include Naming\r\n    include PagePresenters\r\n    include Pagination\r\n    include Scopes\r\n    include Includes\r\n    include ScopeTo\r\n    include Sidebars\r\n    include Routes\r\n\r\n    def resource_class\r\n    def decorator_class\r\n    def resource_table_name\r\n    def resource_column_names\r\n    def defined_actions\r\n    def find_resource(id)<\/pre>\n

Neben Ressourcen kennt ActiveAdmin noch das Konzept der Pages. Deren Initialisierung funktioniert im Wesentlichen \u00e4hnlich, nur dass hier eine spezielle ActiveAdmin::PageDSL<\/code> verwendet wird und als config<\/code> eine ActiveAdmin::Page<\/code> dient.<\/p>\n

Wenn m\u00f6glich, werden die f\u00fcr eine Konfiguration m\u00f6glichen Implementierungen schon bei der Initialisierung von ActiveAdmin erzeugt (etwa Methoden im Ressourcen-Controller). Von Laufzeitdaten abh\u00e4ngige Elemente werden meist in Konfigurationsobjekte gepackt. Diese speichern u.a. Bl\u00f6cke, die dann zur Laufzeit mit den ben\u00f6tigten Daten ausgef\u00fchrt werden k\u00f6nnen. Der Vorgang der Initialiserung ist somit abgeschlossen.<\/p>\n","protected":false},"excerpt":{"rendered":"

ActiveAdmin ist gut dokumentiert und auch ohne Verst\u00e4ndnis der Interna gut zu benutzen. Sp\u00e4testens wenn man eigene Erweiterungen schreiben m\u00f6chte, muss man aber verstehen, wie die Engine funktioniert. Ein Anfang f\u00fcr Version 1.0.0.pre1: Das Modul ActiveAdmin realisiert mittels class << self eine singleton-\u00e4hnliche Instanz von ActiveAdmin::Application: module ActiveAdmin class << self def application @application ||=… ActiveAdmin verstehen: Von der Application zur ResourceDSL<\/span> weiterlesen<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[91],"tags":[608,527,553,552],"_links":{"self":[{"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/posts\/2767"}],"collection":[{"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/comments?post=2767"}],"version-history":[{"count":6,"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/posts\/2767\/revisions"}],"predecessor-version":[{"id":2773,"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/posts\/2767\/revisions\/2773"}],"wp:attachment":[{"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/media?parent=2767"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/categories?post=2767"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sgaul.de\/wp-json\/wp\/v2\/tags?post=2767"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}