A Rails Developer’s impression of CoffeeScript – Part 2

We had a look at the basics of CoffeeScript in the previous post. In this tutorial, we’ll see how it is supported in Rails and how can we use it. Ruby CoffeeScript is a ruby bridge to the CoffeeScript compiler. The coffee-script library will automatically choose the best JavaScript engine for our platform. The available engines are V8, Node.js, and JavaScriptCore.

To use CoffeeScript with Rails 3.0.x

We can use either of the two gems available:
- Barista – gem that provides CoffeeScript support for Rails and Rack apps
- BistroCar – another gem that serves up CoffeeScript from within our Rails application

The latest versions of Barista depends on the coffee-script gem. It auto-detects the available compilers on our system as there are several ways to install CoffeeScript. We can install via node.js as the official documentation suggests or else we can use the therubyracer gem and we won’t have to install anything else! therubyracer includes V8 (the fast Javascript engine from Google).

Finally the coffee-script gem depends on the coffee-script-source gem. This gem contains the CoffeeScript source code and it is synced with official releases.

RubyInside has a good tutorial for installing necessary gems and get CoffeeScript working in Rails projects. It also describes how to use CoffeeScript with jQuery.

Here is what we need to add to our Gemfile :

gem 'therubyracer', :require => false
gem 'barista'

Next, we need to generate barista_config.rb file which is stored in config/initializers/ that contains a set of options to configure Barista options

# Generate barista configuration file
rails g barista:install

The two basic settings for barista are the root and output_root configurations. The default directory where barista looks for your coffeescript files is the coffeescripts folder in your app directory which you need to manually create. We can change this default location by making changes in barista_config.rb.

 c.root = Rails.root.join("app", "scripts")

Similarly, default location for compiled javascript files generated by Barista gem is the public/javascripts directory. Lets say, we want Barista to compile CoffeeScript files into public/javascripts/compiled, we’ll need to add this line to Barista configuration file :

c.output_root = Rails.root.join("public", "javascripts", "compiled")

CoffeeScript with JQuery

To use CoffeeScript with JQuery, the initial setup is as follows -

# Add this to Gemfile
gem "jquery-rails"

# Run bundle install. To invoke the generator, run:
rails generate jquery:install

Lets start by writing the simplest JS statement in CoffeeScript

alert("Hey")

Generated JS -

(function() {
  alert("Hey");
}).call(this);

Well, parenthesis for arguments are optional in CoffeeScript, so we can write

alert "Hey"

So far, so good.

Executing something on document.ready with Jquery

$('#form_tag').bind('blur', () ->
   alert('coffee-script')
)

Doing it this way, the .bind call would executing too soon, before the document is ready and thus it doesn’t do anything. Wrap it in a call to $(document).ready like this

$(document).ready ->
  $('#dummy_form_tag').bind 'blur', ->
    alert 'coffee-script'

Global functions

If we want to make a global function in coffeescript, we can explicitly assign it as a property of the global window object

window.dummyFunc = (dummy_arg) ->
  alert dummy_arg

Sample code to highlight(in red color) all required but empty fields, on clicking the form. Example –

<%= f.text_field :title, :class => 'required' %>

We give ‘required’ class to all the required input text fields.

$(document).ready ->
  $('#dummy_form').bind 'click', ->
    empty_fields = ($(this)).find("input.required")
    if empty_fields.length
      empty_fields.each ->
        $(this).css "background-color", "red"
      false

Generated JS –

(function() {
  $(document).ready(function() {
    return $('#new_post').bind('click', function() {
      var empty_fields;
      empty_fields = ($(this)).find("input.required");
      if (empty_fields.length) {
        empty_fields.each(function() {
          return $(this).css("background-color", "red");
        });
        return false;
      }
    });
  });
}).call(this);

CoffeeScript Demo (GitHub Repo)

This sample Rails application lets us create posts, each post can have multiple sections. It uses Ryan Bates’s Nifty Generator Plugin to generate form layouts and basic skeleton for controllers and models.

Add_More_coffeescript

Clicking the “Add more” link lets us create more sections. This JavaScript functionality has been created using CoffeeScript.

If we clone the repo and run server.. notice the log -

Started GET "/posts" for 127.0.0.1 at 2011-05-13 00:18:25 +0530
[Barista] Compiling all scripts for barista
[Barista] Compiling all coffeescripts

On every request, Barista compiles the coffee files and generates equivalent JavaScript code. Every coffee file in app/coffeescript has an auto-generated corresponding file in public/javascript directory.

Other support

rack-coffee – Serves up coffeescript from rack middleware
After we’ve required ‘rack/coffee’, we put this in the Rails initializer config block:

config.middleware.use Rack::Coffee, :root => "#{RAILS_ROOT}/public"

coffee-haml-filter Custom haml filter for rendering CoffeeScript inside our Haml templates. Sample Code -

 :coffee
    window.cl: s =>
      if typeof(console) != 'undefined' then console.log(s) else s

CoffeeScript in the wild – Is a comprehensive list of all projects that have adopted CoffeeScript.

Coffeebeans gives us inline CoffeeScript

<%= coffee_script_tag do %>
  	alert 'coffee script is awesome!'
<% end %>

Generated JavaScript -

(function() {
  	alert('coffee script is awesome!');
}).call(this);

Rails 3.1 and CoffeeScript

Rails 3.1 will have native CoffeeScript supports(via Sprockets 2). RubyInside has another good tutorial on how to start using CoffeeScript in Rails 3.1. This default can be turned off by commenting out the depedndencies in the generated Gemfile. If we want to write code in JS, we still can – just leave off the .coffee suffix from the filename. The application.js file is no longer shipping with .coffee added for the simple reason that it’ll have no code. But if coffee is available, we’ll be generating JS stubs for new controllers (like helpers) with the coffee extension on). Write .js files, like we were doing before. Be sure not to write coffeescript in .coffee files if we don’t want to use coffeescript. By doing so, we will be using coffeescript. Instead we should only write javascript in .js files.

2 thoughts on “A Rails Developer’s impression of CoffeeScript – Part 2

  1. The time to sell out to a developer, and reap an enormous payoff that will ….. Yes, it’s that kind of script, adapted by Christopher Hampton from his play …

  2. Starting with a clean rvm ruby 1.9.2 gemset, I had to install bundler and i18n to get things moving. Just FYI.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>