Setting up Ember.js with Rails By Nando Vieira January 25, 2015 Read in 5 minutes

Ember.js is a client-side framework that aims single-page applications. It has several tools to abstract the most common patterns. Following the Convention Over Configuration concept, Ember reduces boilerplates for common things, freeing the developer to focus on what really matters: the application.

The most used tool for running Ember apps nowadays is ember-cli. Written with Node.js, generates files and runs the application. Ember-CLI comes with some nice features like asset pipeline and ES6 transpiling. But even with all these features, sometimes you just want to keep your workflow and use Rails.

In this article you’ll see how to set up Ember in a Ruby on Rails app, with testing support using QUnit.

Warning: This article has a new version that uses ember-cli-rails instead. Read the new article.

Installation

To install Ember in your Rails app, just add some gems to your Gemfile . Since jQuery is required, I’ll use Rails Assets, a proxy between Rubygems/Bundler and Bower, so I can have the latest version.

This is how your Gemfile looks like for Rails 4.2 and Ember 1.9.

source 'https://rubygems.org' source 'https://rails-assets.org' gem 'rails' , '4.2.0' gem 'sass-rails' , '~> 5.0' gem 'uglifier' , '>= 1.3.0' gem 'ember-rails' gem 'ember-source' , '~> 1.9.0' gem 'rails-assets-jquery'

You can install the dependencies with bundle install .

Setting up the project

Now is the time to generate your Ember app. Just use the rails generate command. You can also specify your app’s namespace by using the -n switch.

$ rails g ember:bootstrap -n MyApp insert app/assets/javascripts/application.js create app/assets/javascripts/models create app/assets/javascripts/models/.gitkeep create app/assets/javascripts/controllers create app/assets/javascripts/controllers/.gitkeep create app/assets/javascripts/views create app/assets/javascripts/views/.gitkeep create app/assets/javascripts/routes create app/assets/javascripts/routes/.gitkeep create app/assets/javascripts/helpers create app/assets/javascripts/helpers/.gitkeep create app/assets/javascripts/components create app/assets/javascripts/components/.gitkeep create app/assets/javascripts/templates create app/assets/javascripts/templates/.gitkeep create app/assets/javascripts/templates/components create app/assets/javascripts/templates/components/.gitkeep create app/assets/javascripts/mixins create app/assets/javascripts/mixins/.gitkeep create app/assets/javascripts/adapters create app/assets/javascripts/adapters/.gitkeep create app/assets/javascripts/codeplane.js create app/assets/javascripts/router.js create app/assets/javascripts/store.js create app/assets/javascripts/adapters/application_adapter.js

Open app/assets/javascripts/application.js and remove things like jquery-ujs and turbolinks . This is how you should do it:

//= require jquery //= require handlebars //= require ember //= require ember-data //= require_self //= require ./my_app MyApp = Ember . Application . create ();

You also have to create a controller/action that will bootstrap your Ember application. You can go with EmberController#bootstrap . You don’t have add anything to the app/views/ember/bootstrap.html.erb .

class EmberController < ApplicationController def bootstrap end end

Notice that you don’t have to specify the EmberController#bootstrap method, but I like the visibility. Again, remember to create a blank file at app/views/ember/bootstrap.html.erb .

Now it’s time to set up our Rails routes. Ember has support for history.pushState ; This means that every time you visit a route, the URL will change, instead of using the #! scheme. You’ll need a _catch-all route for this to work, so update your config/routes.rb` to something like this:

Rails . application . routes . draw do root 'ember#bootstrap' get '/*path' => 'ember#bootstrap' end

Now create a file at app/assets/javascripts/templates/index.hbs so we can see that everything is working as expected.

<h1> Ember </h1> <p> Fuck yeah! It works! </p>

Finally fire up your server with rails server and head to http://localhost:3000 . You see the following page if you get it right.

Setting up the test environment

Ember has integration with QUnit. So here’s a tip: use it! Otherwise you won’t be able to use all built-in helpers. You also have way more documentation about Ember + QUnit than with any other framework.

Setting up Rails, Ember and QUnit used to be a complicated task; not anymore! I wrote a JavaScript test runner for Rails apps that supports Ember, QUnit, Jasmine and Mocha. Just add test_squad to your Gemfile .

source 'https://rubygems.org' source 'https://rails-assets.org' gem 'rails', '4.2.0' gem 'sass-rails', '~> 5.0' gem 'uglifier', '>= 1.3.0' gem 'ember-rails' gem 'ember-source', '~> 1.9.0' gem 'rails-assets-jquery' group :development, :test do gem 'test_squad' end

You can bootstrap the test environment by running the rails generate command.

$ rails generate test_squad:install --framework ember create test/javascript/unit create test/javascript/unit/router_test.js create test/javascript/routes create test/javascript/routes/.keep create test/javascript/components create test/javascript/components/.keep create test/javascript/views create test/javascript/views/.keep create test/javascript/models create test/javascript/models/.keep create test/javascript/test_helper.js gemfile group :development, :test append Gemfile gemfile rails-assets-qunit append Gemfile source https://rails-assets.org exist test/javascript create test/javascript/test_squad.rb

The generator will detect if you’re running RSpec or TestUnit and will create the structure at spec/javascript or test/javascript .

You may need to modify the test helper file, setting your app’s namespace. It will use your Rails application name by default.

//= require application //= require_self //= require_tree ./components //= require_tree ./models //= require_tree ./routes //= require_tree ./unit //= require_tree ./views // Set the application. App = MyApp ; // Set up Ember testing. App . rootElement = ' #ember-testing ' ; App . setupForTesting (); App . injectTestHelpers ();

The test_squad gem has asset pipeline support, so feel free to use CoffeeScript if you like it.

You can run tests in your browser or, even better, your terminal.

Running tests in your browser

First change your config/routes.rb to add the testing route. This is required only if you’re using the catch-all route and Ember’s history.pushState integration.

Rails . application . routes . draw do root 'ember#bootstrap' get :tests , to: 'test_squad#tests' unless Rails . env . production? get '/*path' => 'ember#bootstrap' end

To run the tests, just start the server in development mode and visit http://localhost:3000/tests .

Running tests in your terminal

First, you need to install Phantom.js. Mac users can do it with Homebrew.

$ brew install phantomjs

If you’re not using Mac, see how you can install Phantom.js.

Just use the rake test_squad command to run all tests.

Extending QUnit

By installing ember-qunit, you’ll be able to use some additional helpers for testing components and models.

Again, we’ll use Rails Assets for this. Add rails-assets-ember-qunit to your Gemfile and install this new dependency with bundle install .

source 'https://rubygems.org' source 'https://rails-assets.org' gem 'rails' , '4.2.0' gem 'sass-rails' , '~> 5.0' gem 'uglifier' , '>= 1.3.0' gem 'ember-rails' gem 'ember-source' , '~> 1.9.0' gem 'rails-assets-jquery' group :development , :test do gem 'test_squad' gem 'rails-assets-qunit' gem 'rails-assets-ember-qunit' end

Load ember-qunit by requiring the library in your test_helper.js file.

//= require application //= require ember-qunit/dist/globals/main //= require_self //= require_tree ./components //= require_tree ./models //= require_tree ./routes //= require_tree ./unit //= require_tree ./views // Set the application. App = MyApp ; // Set up ember-qunit emq . globalize (); App . Resolver = Ember . DefaultResolver . extend ({ namespace : App }); setResolver ( App . Resolver . create ()); // Set up Ember testing. App . rootElement = ' #ember-testing ' ; App . setupForTesting (); App . injectTestHelpers ();

And your done! Now you have helpers like moduleFor , moduleForComponent and moduleForModel , so don’t forget to read the docs.

Installing Ember Inspector

If you want to develop Ember apps, make yourself a favor and install Ember Inspector, a Chrome extension that can inspect your app. You check objects, see rendering times, and more.

Wrapping up

Most applications will have different clients like a web version, mobile (E.g. iOS, Android) and, maybe, a CLI, not to mention SDKs for different languages. The only possible-sane way of doing this is by having an API for all clients. Ember wants to be the final client for web applications (and maybe mobile).

Will it make it?

You can found the source code for this example at Github.