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!

comments powered by Disqus

About Marko Anastasov

Marko co-founded Rendered Text. He’s a programmer with a passion of creating something for other people, coupled with interests in how things work in the society and nature. He is having a great time working across many areas in the company, including product design, helping the engineering teams, empowering users and marketing. He likes to counterbalance it all with running, cycling or a day in the woods.

Suggested Reads

Inject is a fundamental building block

Inject is one of the fundamental, and most versatile constructs available in functional languages. It can be used to implement map, select, max, all? and a bunch of other iteration related methods. Unfortunately, many programmers are not aware of its awesome powers. This article is here to improve this fact.

Contact

Rendered Text is a software company. For questions regarding Semaphore, please visit semaphoreci.com. Otherwise, feel free to get in touch any time by sending us an email.

Rendered Text
Svetozara Miletica 10
21000 Novi Sad
Serbia