-
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 endTo 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 endWhat 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 endNot 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.
-
Customizing Active Admin
I came across a new Ruby on Rails administration framework yesterday called Active Admin, thanks to the latest instalment (episode 165) of The Ruby Show.
I was immediately impressed by the professional landing page and the look and feel of the administration views generated by the gem. I was also very impressed by the elegant DSL. Active Admin is packaged as a gem and it abstracts away all of the tedious administration coding into a simple DSL. The administration files are tucked away under the app folder into a folder of it’s own called admin, and there is one file per resource. I decided to give it a spin and see what it could do.
While playing around with it for an hour or so, I decided to see how far I could push it. Just how flexible is this framework. I added 15 resources to manage in the admin. This pushed the limit of visibility for the menu items at the top of the page, causing them to wrap. It looked ugly and where some resources were two of more words I found the menu item itself would break and wrap splitting the menu item over several lines. I noticed in the screenshot on the Active Admin web site that the Administration menu item had a disclosure indicator. This hinted that the menus could be nested, so I decided to look into it. I found some undocumented options on the menu method, one of which is :parent. By setting a parent you can nest menu items for resources under a top-level menu, and this creates a CSS dropdown menu.
This code generates an Administration menu with three menu items in a dropdown:
# app/admin/administration.rb ActiveAdmin.register Manager do menu :parent => "Administration" end ActiveAdmin.register Backup do menu :parent => "Administration" end ActiveAdmin.register Setting do menu :parent => "Administration" end
and it looks like this:

Another little thing that was slightly annoying was the attribution in the footer. There doesn’t seem to be provision to set the content displayed in the footer of the administration views. I’ve found that Ruby comes to your aid for things like this and by overriding the right method you can put whatever you want in the footer.
The following code overrides the footer content:
# lib/active_admin_views_pages_base.rb class ActiveAdmin::Views::Pages::Base < Arbre::HTML::Document private # Renders the content for the footer def build_footer div :id => "footer" do para "Copyright © #{Date.today.year.to_s} #{link_to('Example.com', 'http://example.com')}. Powered by #{link_to('Active Admin', 'http://www.activeadmin.info')} #{ActiveAdmin::VERSION}".html_safe end end end# app/controllers/application_controller.rb class ApplicationController < ActionController::Base protect_from_forgery # Override build_footer method in ActiveAdmin::Views::Pages require 'active_admin_views_pages_base.rb' end
So far I haven’t found anything that’s restricting the way I want the administration views to function. I’ll be playing around with nested models and things like datetime pickers over the next day or so. I’ll post if I find anything tricky. I’m keen to hear your thoughts on Active Admin.
-
Undo with Paper Trail in Rails 2.3.8
I was recently impressed by Ryan Bates recent Railscast on Undo with Paper Trail, but faced a few difficulties trying to port it into a Rails 2.3.8 project.
Rails 3+ has access to the view_context in the controller. It took me a while to find this because I’ve never needed it, but Rails 2.3.8 has similar access to the link_to helper via @template.
I also found that the undo action taken immediately after a create caused an Activerecord::RecordNotFound error, caused by a redirect_to the show action of the record that was just destroyed.
After fixing these issues I decided to fork Ryan’s source and provide a Rails 2.3.8 version. You can find this at https://github.com/MeetDom/railscasts-episodes/tree/rails238/episode-255. I hope someone else finds this useful.
-
Industrial strength asset packaging in Ruby

BEFORE

AFTER
In the process of getting my first major Ruby application out the door, I’ve been assessing the various asset packaging systems. Asset packaging offers a number of advantages on production websites, including obfuscation through compression of CSS and JS files, and embedding of images and fonts. The biggest advantage however is the speed gained by reducing the number of bits sent to the client from the server.
Jammit offers all of this in a nice ruby friendly gem. It can compress your JS and CSS using either Yahoo’s YUI Compressor, or Google’s Closure. I chose Closure, but installed both (YUI Compressor gem and Closure Compiler gem) in case I decided to change.
Another benefit of Jammit is it’s ability to provide GZIP’d assets if supported. Fonts and images are embedded using Base64, and IE compatibility is provided using MHTML.
All of this is packed up nicely in a small gem. All you have to provide is a small configuration file in the form of YAML, specifying the files to compress and few other options, and it’s all good to go.
I’ve seen amazing performance gains even just in development, especially where webpages have lots of small images referred to in CSS, and with a number of @fontface rules. Admittedly, the results pictured above show development (un-minified) Javascript libraries. However, I’m impressed by the simplicity of installation, and by the gains I’m seeing in development so far. Check it out, and let me know your thoughts.
-
I love the visualization these guys came up with for this. You can read more about how they achieved this using Sass (syntactically awesome stylesheets). I’ve been using Sass for a while now in my Rails projects, and while I love some of the benefits, I’m not totally convinced. I do find myself straying back to plain old CSS syntax from time to time, and I haven’t put my finger on why I’m doing this. Sass has a big brother called Haml, which I’ve used also, but I like it less. It’s probably the fact that Sass is intrinsically tied to Haml, that unconsciously grates on me. I do applaud the efforts of Hashrocket on these DSLs though.