Customizing Active Admin (Part 2)
I've been mucking about with Active Admin, at times trying to bend it to my will. I've been frustrated as hell trying to get it to do some fairly simple stuff, and at times elated when I find a way to do it. The project documentation is, let's say - progressing, and sometimes the best to work things out is to delve into the innards.
I had some success today while integrating the Paper Trail gem into my project. Paper Trail adds versioning of objects. It also permits you to switch to any version at any time, and record information about the nature of the version, for instance, who made the change.
In my project I don't have a standard user, since the project is solely for administration, I have a manager model. Active Admin allows me to choose the model I want as a user object with Devise (for authentication):
# /config/initializers/active_admin.rb ActiveAdmin.setup do |config| config.authentication_method = :authenticate_manager! config.current_user_method = :current_manager end
To integrate paper_trail, I need to tell it who the current user is, by default it's looking for a method in the application controller called current_user. Since I don't have a current user, instead I have a current manager, I need to override a method called user_for_paper_trail. This is typically done in the application controller.
Active Admin provides for a way to include before, after and around filters by adding them to it's config. So I can include a before filter for the overridden method required by paper_trail in the config. This much is clear from the comments in the active_admin config file.
# /config/initializers/active_admin.rb ActiveAdmin.setup do |config| config.before_filter :user_for_paper_trail end
What I was unclear about was where to put my method definition. I can't simply put it in the ApplicationController as that is ignored by Active Admin. I assumed I had to override the admin controller in some way, and include the def block in the active_admin registration block for the model.
This is what I learned eventually, and it seems to work. I am able to wrap my method in a controller block, like this:
# /app/admin/posts.rb ActiveAdmin.register Post do controller do def user_for_paper_trail current_manager end end end
Not very DRY unfortunately because I have to repeat this for every model registration file in the admin folder where I need to override that method. It would be nice to have the ability to override methods in a single place - like the application controller. But it works for now.