Javascript Bootstrapping for Rails

Javascript without bootstrapping is like a drive-in without roller skates. Even though dinner arrives, it’s hard to avoid wondering if it couldn’t get there just a little bit faster.

There are good reasons both in favor of bootstrapping (expedience, performance) and opposed to it (performance, style), but for fast release cycles the former tend to win out. So without further ado or warranty of any kind, here are two ridiculously simple helpers for turning Rails into a lean, mean, lipstick-free-pig-of-a bootstrapping machine. They accept serializable objects, merge duplicates, and spit out the collection(s) on request.

# in application_controller.rb
helper_method :bootstrap_add_data
helper_method :bootstrap_render

def initialize
  @bootstrap_data = ActiveSupport::HashWithIndifferentAccess.new
  super
end

# add data for bootstrapping
def bootstrap_add_data(key, data)
  store = @bootstrap_data[key] || []
  data = [data] if !data.is_a?(Array)
  @bootstrap_data[key] = store | data
end

# render bootstrapped data
def bootstrap_render
  output = ''
  @bootstrap_data.each do |k, v|
    # define the output format
    output += "app[#{k}s] = #{ v.to_json };"
  end
  output.html_safe
end

Two notes on that. First, the output format in bootstrap_render will need to change to match the application. In the example above, data is being rendered on the assumption that the javascript application has a global object (app) that is prepared to receive it. If that isn’t the case, the output variable can be adjusted to match.

Second, I’m not a huge fan of defining helper_methods in controllers. Besides breaking down MVC separation, the fact of the matter is isn’t very elegant at all. But just like there’s no point in pairing a vintage Pinot with American Singles, it’s an easy way to let both controllers and views pass data without all the hassle of trying to dress up ugly.

To use these functions, just call bootstrap_add_data on any objects that should be serialized and delivered up to the application:

<%# In view.html.erb %>
<% bootstrap_add_data 'users', @users %>
<% @users.each do |user| %>
  <p><%= user.name %></p>
<% end %>

The entire collection of serialized objects can then be output using bootstrap_render:

<!-- In layout view, before <script> -->
<script type="text/javascript">
  var app = {};
  <%= bootstrap_render %>
  console.log(app.users);
</script>

And there it is—not pretty, but it’ll do.

Let’s keep in touch

Get noise-free updates on software, product, and process.

Hey, I'm RJ: digital entomologist and intermittent micropoet, writing from the beautiful Rose City.