Define a resource inside an engine - activeadmin/activeadmin GitHub Wiki

To define a resource inside of an engine, use the following technique:

# lib/my_engine/admin/articles.rb
if defined?(ActiveAdmin)
  ActiveAdmin.register Article do
    # customize your resource here
  end
end

Note that it is very important to keep the admin/*.rb definitions out of the Rails' eager load paths to avoid loading these files more than once. If they get loaded multiple times, you are likely to experience weird problems with duplicated filters in the filter forms, duplicate action_item buttons, broken belongs_to definitions, etc. And that will happen only in production (ie. when config.cache_classes = true).

For example, your engine's lib/ folder is a good choice in contrast to its app/ folder (if any). That's because app/ is in the eager load paths and all *.rb files there get recursively loaded by Rails when config.cache_classes = true (usually the case in production environments). However, ActiveAdmin takes care to load these files too and that will be the reason for them to get loaded more than once.

module MyEngine
  class Engine < ::Rails::Engine
    isolate_namespace MyEngine

    initializer :my_engine do
      ActiveAdmin.application.load_paths += Dir[File.dirname(__FILE__) + '/my_engine/admin']
    end
  end
end

The previous code will append your engine's resources to ActiveAdmin's load path. This forces ActiveAdmin to load your resources last, which will not allow them to be overwritten in the main application, but allows the engine creator to keep control over the resource. If you would like to allow the end user to be able to overwrite the resources in the main application, the following code will prepend your engine's resources to ActiveAdmin's load path and allow your resources to be overwritten by the main application. After placing this code in your engine.rb file, simple create the same resource in the main application and customize.

module MyEngine
  class Engine < ::Rails::Engine
    isolate_namespace MyEngine

    initializer :my_engine do
      ActiveAdmin.application.load_paths.unshift Dir[File.dirname(__FILE__) + '/my_engine/admin']
    end
  end
end