Live on the edge with Rails + Ember.js

Tony’s awesome and super helpful original post about Rails + Ember.js is, well, awesome and super helpful. But as long as I’m using the new hotness, I want to use the new new hotness. It’s all in an awesome and super helpful repo by the way, which you can check out here.

Reasoning

Tony has done a great job keeping his tutorial up to date in the last eight months, but I found that there are a few subtle differences to be aware if you want to use ember-rails edge that might trip you up. So to save everyone time and frustration, I’ve done my best to document those changes here. This post details what I had to change from Tony’s tutorial to get it to work for me.

How to Use

Start with Tony’s blog post. Mine is basically a diff of what to do to use edge ember-rails.

Strap It Up

Ok, with the preamble out of the way, let’s get to creating our super-amazing app.

OLD Gemfile:

gem "ember-rails"

NEW Gemfile:

gem "ember-rails", github: "emberjs/ember-rails"

NOTE: We’re just using the latest version of ember-rails, cause we like to live dangerously.

OLD setup:

rails generate ember:bootstrap

NEW setup:

rails generate ember:bootstrap
rails generate ember:install --head

NOTE: The latest builds of ember-data include a new piece we’ll need, and because the latest Ember Data isn’t in ember-rails by default yet (as of 30 Oct 2013), we need to pull down the latest Ember.js and Ember Data. This ensures that you have DS.ActiveModelAdapter available to use, which we will need later.

Setting Up a Resource

I added a second example post so I could see more than one on the home page:

Post.create(title: "A Second Sample Post", body: "This will be our second simple post record.")

The Store

OLD Store.js

DS.RESTAdapter.reopen({
  namespace: "api/v1"
});

EmberTester.Store = DS.Store.extend({
  revision: 11,
  adapter: DS.RESTAdapter.create()
});

NEW Store.js

DS.RESTAdapter.reopen({
  namespace: "api/v1"
});

EmberTester.Store = DS.Store.extend({
  revision: 11,
  adapter: DS.RESTAdapter.create()
});

NOTE: Check out the adapter:’_ams’ line of code. That tells our Ember.js app what adapter to use to communicate with our Rails api, just like the comment says. Now that we’ve told it where to look, everything should be A-OK. I’m not totally sold on this pattern, but we’ll go with it for now.

Routes

OLD app/assets/javascripts/routes/postsroute.js_

EmberTester.PostsRoute = Ember.Route.extend({
  model: function() {
    EmberTester.Post.find();
  }
});

NEW app/assets/javascripts/routes/postsroute.js_

DS.ActiveModelAdapter.reopen({
  namespace: 'api/v1'
});

EmberTester.Store = DS.Store.extend({
  // Override the default adapter with the `DS.ActiveModelAdapter` which
  // is built to work nicely with the ActiveModel::Serializers gem.
  adapter: '_ams'
});

NOTE: There’s probably a good reason why the above code isn’t generated automatically, I just don’t know it yet. Also, If you’re wondering where the PostRoute is, turns out that the default filled in automatically by Ember.js is exactly what we want, so we don’t need to override it. Read about it here (search for ‘common’).

Candybars… I mean, Handlebars

OLD app/assets/javascripts/templates/posts.handlebars

Posts

      {{#each controller}}

    • {{#linkTo “post” this}}{{title}}{{/linkTo}}

{{else}}

  • There are no posts.

 

{{/each}}

{{outlet}}

NEW app/assets/javascripts/templates/posts.handlebars

Posts

      {{#each}}

    • {{#linkTo “post” this}}{{title}}{{/linkTo}}

{{else}}

  • There are no posts.

 

{{/each}}

{{outlet}}

NOTE: Yeah, we don’t need that controller call in there. It doesn’t hurt, per se, but it’s the little things. You may be wondering what {{#each}} is looping over. Well, it just so happens that the posts_route sets the model to be all posts, and smarty pants Ember.js infers that you want to iterate over that collection.

OK, I have some good news and some bad news. The good news is: Yay, you’re done! That wasn’t so terrible, was it? The bad news is: you’ve really just begun, and The Hard Stuff is what comes next. So if you’re hungry for more, go check out:

Further Learning

NOTE: This part is new, and optional (still highly recommended)

Tilde Training – Brought to you by the guys who developed (or should I say, are developing) Ember.js, it shows you how to get started testing your app, adding some more interesting bits of code, and what good Ember code looks like.

Protip: download each repo, cd into it, then…

git tags

to see all the tags. Each tag has a different set of specs for you to get passing. Then…

git checkout -b step_X refs/tags/stepX

where X is a number. Then…

open index.html

and in your browser append “?tests=X” to the url and reload to run the specs.

Good luck and happy hacking!

Also, my thanks to Tony Coconate and Dayton Nolan for suggestions and feedback on how to make this blog post not suck.