Using Controller-specific CSS/JavaScript With Rails Asset Pipeline
While designing my first Rails (3.2) app I found myself wanting to add specific styling and javascript bits to some controllers without affecting others.
I imagined having files named after controllers and make Sprockets automagically include the controller-specific assets based on the context. But how?
Well, we can’t add a require
statement to application.css
or application.js
because that would include the required file for all controllers, and there’s no such thing as a “conditional require”. So how do we do it?
Actually I found out the solution is pretty easy, but there’s a small twist to make it work in production environment.
Assuming you’ll be naming your controller-specific assets something like controller.css.scss
and controller.js.coffee
, you can include them selectively by adding the two following lines to your applications.html.erb
file:
1 2 |
|
This works like a charm in development environment, but if you leave it at that and try to use it in production it will fail. It fails because by default Rails does not precompile assets that are not explicitly referenced by a require
statement (Read more about that on the Rails Asset Pipeline Guide.)
As it turns out, there’s a config variable you can set in config/application.rb
to make Rails explicitly precompile extra assets. You can go ahead and manually add your files to that list:
1
|
|
Hint!
When telling Rails which files you want precompiled, always use the filename the asset will have at the end of the process. So even if you plan to use Sass for a stylesheet and will write a file named
controller.css.scss
, the file you want to inform Rails is simplycontroller.css
.
Ok. But what if I have a bunch of files? Or what if I don’t even know yet which or how many extra files I want precompiled? Having to name them all is too cumbersome, so we’ll tell Rails which files we want precompiled with a RegExp!
1 2 |
|
There it is! So now Rails will precompile all assets, except those starting with an underscore (that way we can even have asset partials), and the solution will work in production environment!
The RegExp is courtesy of Matt Brictson of 55 Minutes. I came across it on a post he made about making Compass work with Rails 3.1/3.2. Apparently you also have to precompile extra assets when using compass. Anyway, thanks Matt!