Don’t Repeat Your Ruby Constants in Javascript

Adarsh Pandit

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.