GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS

Written by thoughtbot

Don’t Repeat Your Ruby Constants in Javascript

Constants help us avoid Magic Numbers and repeated code, which violates the DRY principle.

Recently, I needed to count down the the remaining characters in a text field.

I limited the length of the attribute using a constant:

class Event < ActiveRecord::Base
  NAME_MAX_LENGTH = 70

  validates :name, length: { maximum: NAME_MAX_LENGTH }

  # ...
end

Then I repeated myself in the JavaScript:

# app/assets/javascripts/countdown_event_name.js
var max = 70

"This is a nasty scenario - I've got the same value in two places!", says I. How else could I access the constant more cleanly from my Event model in the JavaScript?

Answer

I discovered you can use ERB in JavaScript if you change file extensions and trigger preprocessing like so:

# Rename countdown_event_name.js → countdown_event_name.js.erb
var max = <%= Event::NAME_MAX_LENGTH %>

Appending .js.erb to the filename initiates asset pipeline preprocessing. Processing occurs in order, right-to-left, so make sure to keep things in order. For example, .js.coffee.erb is processed as ERB first, then processed as CoffeeScript, then served as a JavaScript file for the browser to interpret.