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
--webpackoption:rails new elm_on_rails --webpack=elmIn addition to generating all the standard Rails files and setting up Webpack, this also runs
elm package installwhich 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/javascriptdirectory. You’ll find a generatedMain.elmfile that displays a “Hello Elm!” greeting. And in theapp/javascript/packsdirectory you’ll find ahello_elm.jsfile that embeds the output ofMain.elmin 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.jsembeds the output in the current document. Just to get a quick win, create anapp/views/application/index.html.erbfile. In that file, use thejavascript_pack_taghelper to import thehello_elm.jsfile:<%= javascript_pack_tag "hello_elm" %>Then add a default route in
config/routes.rbto that page:get '/', to: 'application#index' -
Game time! Fire up the Rails server:
rails sIn 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/javascriptdirectory. -
Then paste the following code into a file named
countdown_timer.jsin theapp/javascript/packsdirectory: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
CountdownTimerElm app is embedded in the DOM element with theidofcountdown-timer. -
Import
countdown_timer.jsin yourapp/views/application/index.html.erbfile and add an element with theidofcountdown-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.cssfile:.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
Procfilein 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.