Zack Hubert

Ember.js and Rails, Part 2: Client Side Data

Hey! This article references a pre-release version of Ember. Now that Ember
has reached 1.0, the code samples below are no longer correct and the expressed
opinions may no longer be accurate.

Previously I setup a Rails server to vend the most basic JSON API using the very interesting ActiveModelSerializers gem. Now it’s time to turn my attention to hooking up Ember.js. Specifically my goal in this series is to build a single resource like Rails scaffolding, but have most of the work on the client side and just APIs, auth, and business logic on the server.

First up, let’s use the nifty gem from the Ember.js core team in our Gemfile:

1
gem 'ember-rails'

And bundle…

1
$ bundle install

Next, run the generator to setup the client app skeleton and include the javascripts:

1
$ rails g ember:bootstrap

For me the generator made a slightly weird application specific javascript file (it was .js with comments in the style of Coffeescript) so I made the following tweaks, including adding the .coffee extension:

app/assets/javascripts/ember/app.js.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#= require_self
#= require_tree ./models
#= require_tree ./controllers
#= require_tree ./views
#= require_tree ./helpers
#= require_tree ./templates

# overall app
window.App = Ember.Application.create()

# specify the adapter for accessing with ember-data
App.store = DS.Store.create(
  adapter: DS.RESTAdapter.create(bulkCommit: false)
  revision: 4
)

As you can see, I’m interesting in using ember-data which very much has the feel of a client side ActiveRecord (note: under heavy development with regular breaking changes), so I also needed to add the following to application.js under my ember require:

1
//= require ember-data

And of course we need to declare our client side model:

app/assets/javascripts/ember/models/post.js.coffee
1
2
3
4
App.Post = DS.Model.extend(
  title: DS.attr("string")
  body: DS.attr("string")
)

To make sure everything is working as expected, a quick trip over to the console in my browser shows the plumbing is working!

1
2
3
4
> var posts = App.store.findAll(App.Post)
> var post = App.store.find(App.Post,1)
> post.get('title')
"Hello"

Hurray, we’ve loaded up the data store and been able to query for a specific record. Looking good so far! Next time will be client side routing and layouts.

Updated – I use to have heavy namespacing, but based on this issue I’m going to try Tom’s naming strategy of un-nested namespaces with upper camel case classes (App.MainHomeView) and lower camel case instances (App.mainHomeView).

Comments