Rails 5 makes it easier to sprinkle bits of Elm into your Rails app, or even to go all in with Elm! Here’s a quick rundown of how to start using Elm with Rails:
-
First, create a new Rails 5.1+ app using the
--webpack
option:rails new elm_on_rails --webpack=elm
In addition to generating all the standard Rails files and setting up Webpack, this also runs
elm package install
which downloads and installs the Elm packageselm-lang/core
,elm-lang/html
, andelm-lang/virtual-dom
. -
Now pop open an editor in the application directory and navigate to the
app/javascript
directory. You’ll find a generatedMain.elm
file that displays a “Hello Elm!” greeting. And in theapp/javascript/packs
directory you’ll find ahello_elm.js
file that embeds the output ofMain.elm
in the HTML document:import Elm from './Main' document.addEventListener('DOMContentLoaded', () => { const target = document.createElement('div') document.body.appendChild(target) Elm.Main.embed(target) })
-
You need a page to display the Elm output. Any page will do since
hello_elm.js
embeds the output in the current document. Just to get a quick win, create anapp/views/application/index.html.erb
file. In that file, use thejavascript_pack_tag
helper to import thehello_elm.js
file:<%= javascript_pack_tag "hello_elm" %>
Then add a default route in
config/routes.rb
to that page:get '/', to: 'application#index'
-
Game time! Fire up the Rails server:
rails s
In development, you also need to run a Webpack Dev Server in a separate terminal so that Elm files are automatically compiled as you make changes:
./bin/webpack-dev-server
-
Browse over to http://localhost:3000 and you should see the “Hello Elm!” greeting.
Embed a Countdown Timer
To kick things up a notch and see another example, here’s how to integrate the Elm countdown timer we build in our free Integrating Elm course:
-
Paste CountdownTimer.elm into the
app/javascript
directory. -
Then paste the following code into a file named
countdown_timer.js
in theapp/javascript/packs
directory:import Elm from './CountdownTimer' document.addEventListener('DOMContentLoaded', () => { const target = document.getElementById('countdown-timer') Elm.CountdownTimer.embed(target, { deadline: "May 30 2020 14:05:00" }) })
Notice that the
CountdownTimer
Elm app is embedded in the DOM element with theid
ofcountdown-timer
. -
Import
countdown_timer.js
in yourapp/views/application/index.html.erb
file and add an element with theid
ofcountdown-timer
:<%= javascript_pack_tag "countdown_timer" %> <div id="countdown-timer"></div>
-
The countdown timer relies on a touch of style, so paste the following CSS into the
app/assets/stylesheets/timer.css
file:.time-period { display: inline-block; margin: 3rem 5px; } .time-period .amount { font-size: 300%; padding: 30px; border-radius: 4px; background: #ccc; } .time-period .period { display: block; color: #7B7D7D; text-transform: uppercase; text-align: center; }
-
Reload and the timer should start ticking down! You might need to restart the Webpack Dev Server.
Bonus: Use Foreman
In development, you can sidestep having to run the Webpack Dev Server separately by using the foreman gem.
-
Add the gem to your
Gemfile
:gem 'foreman'
And install it:
bundle install
-
Then create a
Procfile
in the top-level application directory with the following two lines:web: ./bin/rails server webpack: ./bin/webpack-dev-server
-
Now you can start the Rails server and the Webpack Dev Server in one fell swoop using:
foreman start
It’s never been easier to integrate Elm into a Rails app, and it will likley only get smoother from here!
Build a complete Elm web app from scratch!
Quickly get up to speed with Elm and functional programming as you build a reactive web app step-by-step in our 3.5-hour Building Web Apps With Elm course.