Marko Anastasov wrote this on September 30, 2011
A convention for using CoffeeScript with Rails
On a recent new project we’ve had the opportunity to make the leap and use CoffeeScript exclusively for client-side scripting. This post describes a convention we came up with for using it with Rails.
Typically what we’d previously do is write a JavaScript “class” like this:
Our needs are usually modest and the class is in fact acting just like a namespace with a name that corresponds to the resource it’s being used on. We’d run the jQuery function and call our functions, often passing some resource-specific arguments, such as paths, inside a view file like this:
By default, the new asset pipeline in Rails 3.1 bundles all JS files in one. That’s good because it can be minified and downloaded by the web browser only once with a single HTTP request. That influences how you structure your code if you want to keep it that way (we do). But in the beginning my first attempt was just to mimic what I did before, and it looked something like this:
I learned that I need to prefix a function or class with window.
to make it global, because the CoffeeScript compiler wraps all code in an anonymous function and doesn’t pollute the global scope.
Then I looked for a way to embed CoffeeScript in a view file. I found a gem called coffeebeans, which implements a coffee_script_tag
helper. So in my view file I had:
The whole thing felt a little messy, so at a morning standup we talked about how to make it better. We realized that our goal is to have everything in coffee files and somehow pass these functions data that is determined at rendering time.
We came up with this:
- Every view file renders data required for CoffeScript as data attributes in the body tag.
- Every coffee file has a jQuery function which is conditionally executed if the
data-prefix
attribute matches the expected value. - Nothing is globally exported unless shared between different coffee scripts.
- Views do no contain any script.
Here are two helper methods we use:
The view can call page_data
like this:
We also have a little CoffeeScript helper to read the data attributes:
Finally, a coffee file as per this convention:
That would be it so far. There may be a better way, so we’d love to see how you are doing it!