Ember
- Client-side MVC framework
- Sequel of SproutCore
- Plays nicely with Rails
z, ? | toggle help (this) |
space, → | next slide |
shift-space, ← | previous slide |
d | toggle debug mode |
## <ret> | go to slide # |
c, t | table of contents (vi) |
f | toggle footer |
r | reload slides |
n | toggle notes |
p | run preshow |
P | toggle pause |
Sensible defaults for API only applications:
class ProductsController < ApplicationController
def show
product = Product.find(params[:id])
if product
render :json => product
else
render :json => {}, :status => 404
end
end
end
Flexible serialization of ActiveModel objects:
class ProductSerializer < ActiveModel::Serializer
attributes :id, :name, :price
def include_price?
current_user.admin?
end
end
Draw your own routes:
App::Application.routes.draw do
devise_for :users, :skip => [:sessions]
devise_scope :user do
post '/users/sign_in' => 'sessions#create'
delete '/users/sign_out' => 'sessions#destroy'
end
end
Specialize the session controller:
class SessionsController < Devise::SessionsController
def create
resource = resource_from_credentials
data = {
user_id: resource.id,
auth_token: resource.authentication_token
}
render json: data, status: 201
end
def destroy
resource = resource_from_token
render json: {user_id: resource.id},
status: 200
end
end
Auth.Config.reopen({
tokenCreateUrl: '/users/sign_in',
tokenDestroyUrl: '/users/sign_out',
tokenKey: 'auth_token',
idKey: 'user_id',
signInRoute: 'sign_in',
authRedirect: true,
signInRedirectFallbackRoute: 'index',
signOutRedirectFallbackRoute: 'index'
});
App.SignInController = Auth.SignInController.extend({
signIn: function () {
this.registerRedirect();
Auth.signIn({
email: this.get('email'),
password: this.get('password')
});
}
});
App.ProductRoute = Auth.Route.extend({
model: function(params) {
if (Auth.get('authToken')) {
return App.Product.find(params.product_id);
}
return {};
}
});
describe ProductsController do
describe "GET show" do
let!(:product) { Fabricate(:product) }
it "returns our product" do
get :show, id: product.id
m = JsonPath.on response.body, '$.product.name'
expect(m.first).to eq(product.name)
end
end
end
Ember.testing = true;
Konacha.reset = function() {};
App = null;
Ember.run(function() {
App = Ember.Application.create();
App.deferReadiness();
});
App.Router.reopen({
location: 'none'
});
describe("login form", function() {
before(function() {
Ember.run(function() {
Demo.advanceReadiness();
});
});
before(function() {
this.xhr = sinon.useFakeXMLHttpRequest();
var requests = this.requests = [];
this.xhr.onCreate = function (xhr) {
requests.push(xhr);
};
});
it("sends user credentials", function() {
Ember.run(function () {
Ember.View.views["signin-email"].set(
'value', "john@users");
Ember.View.views["signin-password"].set(
'value', "secret");
});
Ember.run(function () {
$("#signin-submit").click();
});
expect(this.requests[0].requestBody).to.equal(
'{"email":"john@users","password":"secret"}'
);
});
});
feature "Signing up", :js => true do
given!(:user) { Fabricate(:user) }
scenario "Signing in with correct credentials" do
visit "/"
fill_in "signin-email", :with => user.email
fill_in "signin-password", :with => user.password
click_on "signin-submit"
page.should have_button("signout")
end
end