Zack Hubert

Ember.js and Rails, Part 1: Rails Setup

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.

Today, I’d like to look at building an app with a Rails server-side implementation and an Ember.js client. The goal of this post is to get Ember and Rails integrated and a single resource fully wired up.

I’ve done some work in Backbone.js and Spine.js, but the Keynote by @wycats yesterday has motivated me to take a look at Ember, so let’s dig in.

First up the Rails side of the equation (Rails 3.2.3):

1
$ rails new ember-rails-demo

After the usual bundling and such, we want to install ActiveModelSerializers to make our creation of JSON a bit easier. You could just use jBuilder or .as_json hashes, but I think AMS will pay off in spades over the course of a large project so let’s use that here.

First add the following to the Gemfile:

1
gem "active_model_serializers", :git => "git://github.com/josevalim/active_model_serializers.git"

And rebundle…

1
$ bundle install

Now let’s make our single resource and a serializer:

1
2
$ rails g resource post title:string body:string
$ rails g serializer post title body id

And put the basics into our posts_controller:

app/controllers/posts_controller.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class PostsController < ApplicationController
  def index
    @posts = Post.all

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @posts }
    end
  end

  def show
    @post = Post.find(params[:id])

    respond_to do |format|
      format.json { render json: @post }
    end
  end

  def create
    @post = Post.new(params[:post])

    respond_to do |format|
      if @post.save
        format.json { render json: @post, status: :created, location: @post }
      else
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

  def update
    @post = Post.find(params[:id])

    respond_to do |format|
      if @post.update_attributes(params[:post])
        format.json { render json: nil, status: :ok }
      else
        format.json { render json: @post.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @post = Post.find(params[:id])
    @post.destroy

    respond_to do |format|
      format.json { render json: nil, status: :ok }
    end
  end
end

One cool thing about AMS is that expects to integrate with a scope for auth (this enables authorization of what attributes and associations are available via serialization), in most cases current_user so let’s install Sorcery to have something for it to work with. If I was building a real system, there would be more steps to take here, but it’s trivial and I don’t want to waste space on it.

In Gemfile:

1
gem 'sorcery'

And rebundle…

1
$ bundle install

Finally, run the install generator…

1
$ rails generate sorcery:install

And get our database up to speed…

1
2
$ rake db:create
$ rake db:migrate

Let’s put some dummy data into seeds.rb:

db/seeds.rb
1
2
Post.create(title: 'Hello', body: 'world')
Post.create(title: 'foo', body: 'bar')

Running the server and calling the API we see some serialized posts. Woot!

1
2
3
$ rails server
$ curl localhost:3000/posts.json # from another window
{"posts":[{"title":"Hello","body":"world"},{"title":"foo","body":"bar"}]}%

Some final cleanup…set default route in config/routes.rb:

1
2
3
4
EmberRailsDemo::Application.routes.draw do
  resources :posts
  root :to => 'posts#index'
end

And make an app/views/posts/index.html.erb (remove public/index.html)

1
<h1>Posts</h1>

Of course there will be more to do with this view, but at least the app can run cleanly at this point, so let’s stop here.

Posted by Zack Hubert emberjs, rails

« Getting Started with Octopress Ember.js and Rails, Part 2: Client Side Data »

Comments

gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.