At the time of writing, Ember CLI requires the user to adjust entries in bower.json and node.json if they would like to use more current stable Ember versions than Ember.js 1.13.8.

A comment by Stefan Penner links blueprints one can use for bower.json and package.json. Those blueprints list current stable working versions of the default packages typically installed when setting up an Ember app with the Ember CLI. I tried setting up a new Ember app with updated files and the blueprints are working just fine for me.

The following is a procedure for setting up a new Ember app with the current Bower components and Node modules.

We start out creating the app and deleting the default Bower and Node package versions:

ember new my_ember_frontend
cd my_ember_frontend
rm -R bower_components/*
rm -R node_modules/*

Then we replace the contents of bower.json with the contents of this bower.json and we replace the contents of package.json with the contents of this package.json.

In the package.json, we need to insert the version number of the Ember CLI we use into the line "ember-cli": "<%= emberCLIVersion %>", between the second pair of quotation marks.

We can mention the name of our app in both files in the respective entry. Also, we can add version and description of our app to the respective lines in the package.json.

Now we can

bower install
npm install

and we have created a new Ember app with Ember CLI using current stable packages.

Thanks to Diego Poza, the author of this article, for initial instructions!

Rails API has been merged into Rails master branch.

There is a how-to on building a Rails API app and integrating it with a simple Ember app. There also is a redux from one year before the merge, which explains how an Ember and Rails API app could be built before the Rails API merge.

In this post, we are going to build a simple Rails API app and an Ember app from scratch and give the Ember app access to the Rails API. This consolidates the approaches described in the two posts linked above.

Build the Backend

For a more in-depth explanation of what is happening here, consult this post.

Generate Rails API only application

Rails 5 at the time of writing requires Ruby 2.2.2 or newer. For instance, in case you are using rvm, do rvm install 2.2.3. To use this version as your system default, rvm use 2.2.3 --default.

Since Rails 5 is not yet released, we have to clone the Github repository and generate our application from the source code.

git clone git://github.com/rails/rails.git
cd rails
bundle
bundle exec railties/exe/rails new ../my_api_app --api --edge

Scaffold Users resource

We create a simple scaffold using rails generate scaffold and perform the migration:

cd ../my_api_app
bin/rails g scaffold user name
bin/rake db:migrate

Adjust JSON serialization format

Ember’s REST adapter requires that the root object’s key is present in the JSON payload. This is achieved by setting the json adapter instead of Active Model Serializer’s default flatten_json adapter.

Create a new initializer file config/initializers/ams_json_adapter.rb including the following line:

1
ActiveModel::Serializer.config.adapter = :json

Test Rails API

To see if the API works as expected, start the server with bin/rails s. Let us try to create the first User using curl:

curl -H "Content-Type:application/json; charset=utf-8" \
-d '{"user": {"name":"Hans"}}' http://localhost:3000/users

Looking at localhost:3000/users, we now expect to see the newly created user shown in the format we specified above.

Set up CORS

Whenever the Rails app and the Ember app have different origins, we need to configure Cross Origin Resource Sharing (CORS).

We will test the backend in localhost:3000 and the frontend in localhost:4200.

In brief, we have to uncomment rack-cors in the Gemfile, run bundle, and put the following code in config/initializers/cors.rb:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Avoid CORS issues when API is called from the frontend app
# Handle Cross-Origin Resource Sharing (CORS) in order to accept cross-origin AJAX requests

# Read more: https://github.com/cyu/rack-cors

 Rails.application.config.middleware.insert_before 0, "Rack::Cors" do
   allow do
     origins 'localhost:4200'

     resource '*',
       headers: :any,
       methods: [:get, :post, :put, :patch, :delete, :options, :head]
   end
 end

Build the frontend

This instruction will enable the Ember app to use a simple Users resource it receives from the Rails API. It will present the API data as a Users index page. For additional detail (e.g. show User pages), we can refer to the post this is based on.

Install Ember CLI and create frontend

For installing the Ember CLI, we use --no-optional, since it is less error-prone. Using nvm, we do not need to run npm as root, thus avoiding possible permission problems:

npm install -g ember-cli --no-optional

Create the Ember.js app:

cd ..
ember new my_ember_frontend
cd my_ember_frontend

At the time of writing, this yields a reminder even with the current stable Node.js: Future versions of Ember CLI will not support v4.1.0. Please update to Node 0.12 or io.js. Do not worry: the fix for this misleading message has been announced and is likely to find its way into future versions of Ember CLI.

Generate application adapter

To enable the Ember app to communicate with our Rails app, we generate an adapter:

ember generate adapter application

Now we adjust app/adapters/application.js:

1
2
3
4
5
import DS from 'ember-data';

export default DS.ActiveModelAdapter.extend({
  host: 'http://localhost:3000'
});

Add Users resource to router.js

Edit app/router.js:

1
2
3
4
5
6
7
8
9
10
11
12
import Ember from 'ember';
import config from './config/environment';

var Router = Ember.Router.extend({
  location: config.locationType
});

Router.map(function() {
  this.resource('users');
});

export default Router;

Generate User model

Firstly,

ember generate model user

Then edit app/models/user.js:

1
2
3
4
5
import DS from 'ember-data';

export default DS.Model.extend({
    name: DS.attr('string')
});

Generate Users/index route

Now,

ember generate route users/index

Edit app/routes/users/index.js:

1
2
3
4
5
6
7
import Ember from 'ember';

export default Ember.Route.extend({
    model: function() {
        return this.store.findAll('user');
    }
});

Write Users/index template

Edit app/templates/users/index.hbs:

<ul>

    {{#each model as |user|}}

    <li> {{user.name}} </li>

    {{/each}}

</ul>
{{outlet}}

Test the application

To test the whole application, run from the Rails app’s directory

bin/rails s

and from the Ember app’s directory

ember serve

Browse to localhost:4200/users to try it out!

Many thanks go out to Moritz for proofreading this post!