Getting Ember.js working in a Rails engine

Posted on Aug 16, 2014 in Blog

This is a quick guide outlining how I got ember.js and ember-rails setup and working inside a Rails 4.1 engine.

Step 1. Add ember-rails and ember-source to my gemspec for my engine.

s.add_dependency 'ember-rails'
s.add_dependency 'ember-source'

Step 2. Require ember-rails in my engine.rb file.

I had to require ‘ember-rails’ in my engine.rb file in order to be able to run rails g ember:bootstrap. When I didn’t add require ‘ember-rails’ to my engine.rb I got the following error:

require 'ember-rails'
module Hanuman
 class Engine < ::Rails::Engine
   isolate_namespace Hanuman
 end
end

Step 3. Bootstrap ember-rails

rails g ember:bootstrap -g --javascript-engine coffee

See https://github.com/emberjs/ember-rails for more information about what ember-rails bootstrap does.

Step 4. Add ember configuration information to engine

According to ember-rails we need to set the config.ember.variant = :development  in our development.rb file. Rails engines don’t come with a development.rb file out of the box. However, you can create one. In your engine create a environment directory in the config directory. Then create a development.rb file and add the following line:

Emberengine::Engine.config.ember.variant = :development

I also created a production.rb file and added this line:

Emberengine::Engine.config.ember.variant = :production

Step 5. Create rails controller to interact with ember.js

I created a home controller with and index action so that I could have a placeholder to invoke my ember code.

rails g controller home index

Step 6. Test ember keeping handlebars templates inside rails view

I added the following handlebars templates to my index.html.erb.

<script type="text/x-handlebars">
 <h2>Welcome to Ember.js</h2>
 {{outlet}}
</script>

<script type="text/x-handlebars" id="index">
 <h2>in index route</h2>
 <ul>
 {{#each item in model}}
 <li>{{item}}</li>
 {{/each}}
 </ul>
</script>

Then I added the following to my router.js file. This code follows the emberjs starter kit example.

Emberengine.IndexRoute = Ember.Route.extend({
 model: function() {
 return ['red', 'yellow', 'blue'];
 }
});

Then I went to http://localhost:3000/emberengine/home/index to test my basic emberjs and rails integration. It worked.

Step 7. Setup asset pipeline to use handlebars templates stored in ember-rails templates directory

Now we really want our handlebars templates stored in the templates directory in app/assets/emberengine/templates. This is where ember-rails expects you to put them. To get these templates working I had to finagle my asset manifest file and add the following configuration:

Emberengine::Engine.config.handlebars.templates_root = "emberengine/templates"

For this configuration setting I created an ember.rb file inside config/initializers. I also had to create the initializers folder.

Step 8. Get manifest files just right so that templates are available to emberjs.

ember-rails recommends creating a single manifest file referencing your handlebar templates and then adding a reference to that manifest file in your application layout. Since I was developing an engine I didn’t want to mess with my application layout. Instead I added the reference to my templates in my application.js manifest after requiring my emberengine manifest. See below.

application,js

// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require handlebars
//= require ember
//= require ember-data
//= require_self
//= require ./emberengine
//= require ./templates/all

// for more details see: http://emberjs.com/guides/application/
Emberengine = Ember.Application.create({
 LOG_TRANSITIONS: true
});

//= require_tree .

emberengine.js

//= require ./store
//= require_tree ./mixins
//= require_tree ./models
//= require_tree ./controllers
//= require_tree ./views
//= require_tree ./helpers
//= require_tree ./components
//= require ./router
//= require_tree ./routes
//= require_self

Code on github

I’ve uploaded my source code for the engine and the parent application for you to reference.

The parent app: https://github.com/kristenhazard/ember-engine-app

The engine: https://github.com/kristenhazard/emberengine

If you have any questions we are @suntouchers on twitter. We’ll be happy to help if we can.

Thank you Ember core team and ember-rails contributors for your work.