James Herdman

Public Asset Bundling in Rails

Sometimes, in larger Rails projects, we want to group together JavaScript or CSS files. Let’s use the the Uploadify project to illustrate how we can use a seldom discussed Rails feature to simplify inclusion of CSS and JavaScript files that are used in conjunction with each other: ActionView::Helpers::AssetTagHelper.

Materials

Considering the Norm

Rails defines a set of default JavaScript files to include in our view when we use #javascript_include_tag(:default). From the Rails documentation we can see an example of the output:

javascript_include_tag :defaults # =>
    "<script type='text/javascript' src='/javascripts/prototype.js'></script>
    <script type='text/javascript' src='/javascripts/effects.js'></script>
    ...
    <script type='text/javascript' src='/javascripts/application.js'></script>"

This is called an expansion. We have expansions for JavaScript and Stylesheets. We can use with both #javascript_include_tag and #stylesheet_link_tag. We can also register our own. It’s through expansions that we can bundle together JavaScript and and CSS files.

Registering Expansions

Registering expansions is done through two different methods: ActionView::Helpers::AssetTagHelper.register_javascript_expansion, and ActionView::Helpers::AssetTagHelper.register_stylesheet_expansion. Each of these methods takes a Hash as an argument which points to a list of asset names (e.g. “jquery.js”).

Let’s look at how we would define the default :default for our JavaScript bundle:

ActionView::Helpers::AssetTagHelper.register_javascript_expansion :default => [
  'prototype',
  'effects',
  ...
  'application'
]

That’s a little verbose for setting the default, so Rails provides us ActionView::Helpers::AssetTagHelper.register_javascript_include_default. Let’s try this again:

ActionView::Helpers::AssetTagHelper.register_javascript_include_default(
  'prototype',
  'effects',
  ...
  'application'
)

Let’s set a default using jQuery:

ActionView::Helpers::AssetTagHelper.register_javascript_include_default(
  'jquery',
  'application'
)

Easy as pie! Let’s setup expansions for Uploadify:

ActionView::Helpers::AssetTagHelper.register_javascript_expansion :uploadify => [
  'swfobject',
  'uploadify',
]

ActionView::Helpers::AssetTagHelper.register_stylesheet_expansion :uploadify => [
  'uploadify'
]

Now we can easily maintain asset bundles. Cool, eh?