On Github DVG / ember_on_rails
Prepared by Bradley Temple
# Gemfile gem 'ember-rails' # for bootstrapping gem 'ember-auth-rails' # if you need authentication gem 'active_model_serializers' # Helpful in rendering JSON
$ bundle install $ rails g ember:bootstrap
You'll have several new directories in app/assets/javascripts
Routes are the starting point with an Ember app. The url is the first thing you are encouraged to think about.
# app/assets/javascripts/router.js.coffee App.Router.map -> @route "articles", path: '/'
The Router serves much the same function as it does in Rails. It takes a given URL and translates it to a route object. In this case we are mapping root to the articles route.
# app/assets/javascripts/routes/articles.js.coffee App.ArticlesRoute = Ember.Route.extend model: -> App.Article.find() # with no argument this will send findAll()
You basically have three options:
Use EmberData Use EmberModel Plain 'ol Jquery $.ajax$ cd app/assets/javascripts $ mkdir lib && cd lib $ wget https://raw.github.com/ebryn/ember-model/master/ember-model.js
Don't forget to include it in application.js
# app/assets/javascripts/routes/articles_route.js.coffee App.Article = Ember.Model.extend id: Ember.attr() title: Ember.attr() body: Ember.attr() comments: Ember.hasMany('App.Comment', {key: 'comments', embedded: true}) App.Article.adapter = Ember.RESTAdapter.create() App.Article.url = "/api/v1/article" # REST endpoint App.Article.collectionKey = "article" # the root JSON key for a collection App.Article.rootKey = "article" # the root JSON key for an individual item
Something important to remember when building a rich front-end client is that your Rails app is now an app exposed through an API. Therefore, it's a good idea to namespace the routes like so:
namespace :api do namespace :v1 do resources :articles resources :users end end
Cheap and Fast Version
gem "inherited_resources"
class BaseController < ApplicationController inherit_resources respond_to :json before_filter :default_json protected def default_json request.format = :json if params[:format].nil? end endThis will define the basic restful actions for you, only respond to JSON requests and will default any request wehre the format cannot be determined to json.
If you use EmberData's REST Adapter, sometimes it sends some oddly formatted collection requests. You can get around it like this (inherited resources hack):
class BaseController < ActiveRecord::Base # ... code omitted def collection get_collection_ivar || begin c = end_of_association_chain coll = c.respond_to?(:scoped) ? c.scoped : c coll = params[:ids] ? coll.find(params[:ids]) : coll.all set_collection_ivar(coll) end end end
Nothing much special here
class Article < ActiveRecord::Base attr_accessible :title, :body has_many :comments end
You can use this to serialize your JSON response in a way that makes sense to you. In the most basic, you just pass it a list of attribtues:
class ArticleSerializer < ActiveModel::Serializer attributes :id, :title, :body has_many :comments end
You can also define a method to return something more specific
class ArticleSerializer < ActiveModel::Serializer attributes :id, :title, :body, :image_url has_many :comments def image_url object.image(:thumb) end endd
We've got a route that sends a request to the rails app, and the rails app now renders JSON back to us. now we just need to display something to the user
This basically works like the application layout in Rails, though since the Ember app is rendering inside the application layout, you don't need to worry about boilerplate html
<h1>My Awesome App</h1> {{outlet}}outlet works like yield. It's the place ember will render a given template.