Subscribe now

Elm components in a Rails application [06.29.2017]

Adding Elm Components in our Rails app

Yesterday, we saw how to use React inside our Rails app. Today we will see how simple it is to use Elm components in our Rails 5.1 application.

Let's create a Rails application, and we will pass elm as a webpack parameter.

rails new my-rails-app-with-elm --webpack=elm

It adds the elm core package in our application and we should be fine to use Elm inside our Rails app.

Let's start our project

cd my-rails-app-with-elm
rails s

And if we check http://localhost:3000 we should see that we're on Rails.

Creating a controller and see our Elm Component

As when we used React with our Rails application, our components are located in: app/javascript/packs. In this installation, we can see a simple Elm component:

module Main exposing (..)

import Html exposing (Html, h1, text)
import Html.Attributes exposing (style)

-- MODEL

type alias Model =
  {
  }

-- INIT

init : (Model, Cmd Message)
init =
  (Model, Cmd.none)

-- VIEW

view : Model -> Html Message
view model =
  -- The inline style is being used for example purposes in order to keep this example simple and
  -- avoid loading additional resources. Use a proper stylesheet when building your own app.
  h1 [style [("display", "flex"), ("justify-content", "center")]]
     [text "Hello Elm!"]

-- MESSAGE

type Message
  = None

-- UPDATE

update : Message -> Model -> (Model, Cmd Message)
update message model =
  (model, Cmd.none)

-- SUBSCRIPTIONS

subscriptions : Model -> Sub Message
subscriptions model =
  Sub.none

-- MAIN

main : Program Never Model Message
main =
  Html.program
    {
      init = init,
      view = view,
      update = update,
      subscriptions = subscriptions
    }

We need to import the Javascript using webpacker. So, we have a hello_elm.js that uses our Elm Component.

import Elm from './Main'

document.addEventListener('DOMContentLoaded', () => {
  const target = document.createElement('div')

  document.body.appendChild(target)
  Elm.Main.embed(target)
})

Let's create a controller Pages and a method index where we will use our component.

rails g controller Pages index

Let's change our Pages index and import our Elm Component. In this case, we will import the javascript that wraps our Elm component, hello_elm and not our Main.elm elm code.

<h1>Pages#index</h1>
<p>Here we will import our Elm Component:</p>
<%= javascript_pack_tag 'hello_elm' %>

Once we enter in /pages/index, boom! We can see our Elm Component. It's also possible see the Elm Debugger. If we close webpacker, we cannot see the Elm component and we get connection refused. Once we start the webpac dev server again, we can see the component working correctly. So, if you're working like this, make sure your webpack server is running.

The webpack dev server is always running and it watches the changes in our project. In this case, let's change our Elm code and see if it updates automatically in our Rails app.

It does! If we change our Elm code, it compiles the code and it generates the correct file for us. This is great! So, if you're doing something like that, you can just work inside your elm code and it should be fine.

Deploying our App to Heroku

We saw how to create an Elm app integratig with Rails, and we saw in a previous episode how to integrate our React Components with Rails. These things are using webpack, such things are possible since Rails 5.1. How can we deploy that to a server? Let's say Heroku? Let's do that!

We will need to change sqlite to postgres:

vim Gemfile
gem 'pg'

And we will need to change our config/database.yml file:

default: &default
  adapter:  postgresql
  host:     localhost
  encoding: unicode
  pool:     5
  username: <%= ENV['PGUSER'] %>
  password: <%= ENV['PGPASSWORD'] %>

staging:
  <<: *default

development:
  <<: *default
  database: my-rails-elm-project-development

test:
  <<: *default
  database: my-rails-elm-project-test

production:
  <<: *default
  database: my-rails-elm-project-production

After that, we can just create the database, and run the migrations, but we don't have any migrations. Start the server, and our app should look the same.

Now, to deploy your app in Heroku is very simple. We can do this via the command line, or you can go to the website and just create an app for yoursef. In our case, we will keep it simple, and let Heroku create a random name for our app.

To do that, you should be logged in to your heroku CLI.

heroku create

Ok! It has created our app! It also has added a git remote called heroku that we can push to. Once we push to this, it deploys our app.

Let's do that!

git push heroku

As you can see, it says we have a buildpack for javascript and rails. Some time ago, we added two buildpacks to our app: Node and Rails. But now, Heroku already knows we have a Rails 5.1 application and it does it for us! Really easy!

Ok, now we can see our app! Let's go to pages/index. And Boom! We can see our app working and deployed in a server!

Summary

Today we saw how to use Elm in our Rails project. We also saw how to deploy our Rails 5.1 Application using webpak in Heroku.

Resources