Ember.js for Rails
Developers
Tech Talk - Feb. 21, 2014
Aaron Ortbals
What we’ll be doing
•

Building a Github Stat Tracker in Ember

•

Work alone or in pairs

•

Discuss various aspects of u...
You’ll Need
•

Homebrew

•

Git

!

brew install git!
•

!

Ruby
brew install rbenv ruby-build!
rbenv install 2.0.0-p353 #...
Build Tools
•

A build system:
•
•

prepares them for deployment

•

•

compiles your assets

serves them in development

...
Comparing Toolsets
•

ember-rails (what we are using)!
•

•

ember-app-kit!
•

•

rake, sprockets, internal REST API, ruby...
Future Build Tools
•

Broccoli is a build system meant to alleviate many
of the issues with grunt (and others)

•

Goal of...
What's in the repo
•

I've built a basic Rails 4 API that we can use to
consume Github

•

Turbolinks is removed

•

Provi...
What’s in the repo
•

SCSS
•

Bourbon: SCSS mixins

•

Bourbon Neat: semantic grid

•

Bitters: predefined typography, list...
v0.1

How we’ll work
•

Checkout a tag and make a practice branch
!
git checkout v0.1!
git checkout -b practice!

•

Follo...
Ember Rails, Releases
•

Gemfile	

!
...	
gem 'ember-rails'	
gem 'ember-source', '~> 1.4.0'	
gem 'ember-data-source', '~> ...
v0.1

Generating Ember
Scaffolding
•

Let's start by using ember-rails to generate our
directory structure
!
rails generat...
v0.2

Namespaced API
•

Let's setup our Rails API and configure Ember

!
EmberGithubExample::Application.routes.draw do!
ge...
One view, one controller
•

app/controllers/app_controller.rb	

!
class AppController < ApplicationController!
def index!
...
v0.2

Setup our rails application
template
•

Bundle all templates together thanks to Sprockets

•

views/layouts/applicat...
v0.2

Configure Ember's
namespace
•

store.js	
!
EmberGithubExample.ApplicationAdapter =
DS.ActiveModelAdapter.extend!
name...
v0.2

Setup the Ember app
•

application.js.coffee

- better logging in dev

!
window.EmberGithubExample = Ember.Applicati...
v0.2

Let's hello world!
•

Ember will render the default application.hbs

!
<header>Welcome to the Github Stat Tracker!</...
v0.2

Using Bower with Rails
•

Bower is a client-side package manager

•

Don't vendor stuff. Just don't.

•

.bowerrc	

...
v0.2

Ember Data
•

Makes it easy to retrieve records from the server

•

Abstracts away the request/response cycle with a...
v0.2

Talking with Github
•

We have a basic REST API to query events for an
organization
!
localhost:3000/api/events?org=...
v0.2

Models
•

A model looks like this:

!

App.User = DS.Model.extend!
  firstName:  DS.attr('string')!
  lastName:   DS...
v0.2

Building some models
[	
{	

•

Repo

•

Actor

•

Org

•

"type": "Event",	
"public": true,	
"payload": {	
},	
"repo...
v0.3

Event
EmberGithubExample.Event = DS.Model.extend!
type:
DS.attr('string')!
public:
DS.attr('string')!
createdAt: DS....
v0.3

The Adapter
•

Ember has what is called 'the adapter'

•

The adapter is responsible for translating data from
a RES...
v0.3

Polymorphic Associations!
App.Like = DS.Model.extend!
user:
DS.belongsTo('user')!
likeable:
DS.belongsTo('likeable',...
v0.4

Router
•

Ember represents each of the possible states in your
application as a URL
!

interacts

event

!
•

The us...
v0.4

Router Example
!
•

Static routes
!

•

Resource routes

•

Nested resources

App.Router.map (match) ->!
  @route 'a...
v0.4

A route
•

Each route has a route handler

•

It finds the model, hands it to the controller, and
renders a template
...
v0.4

Declare our route
•

https://api.github.com/orgs/chaione/events

!
EmberGithubExample.Router.map ()->!
@resource 'or...
v0.4

Event Route
•

A Route provides a model hook

!
EmberGithubExample.EventsRoute = Ember.Route.extend!
model: (params)...
v0.4

Event Template
•

Ember uses Handlebars which wraps {{things}} in
curly braces

!
<div class="main">!
<div class="im...
v0.4

Events Template
•

In the events template we loop over the route
model
!
<section class="results">!
{{#each model}}!...
v0.4

Controllers handle actions
•

Controllers handle actions on your current view
•

•

form submissions, clicks, etc

T...
v0.4

Events Controller
EmberGithubExample.ApplicationController =
Ember.Controller.extend!
queryField: null!
actions:!
se...
v0.4

What do we have so far?
•

Models - represent our data from the server

•

Router - declared route for our URL

•

R...
v0.5

Computed Properties
App.Person = Ember.Object.extend!
firstName: null!
lastName: null!
!
fullName: (->!
"#{@get('fir...
v0.5

Add the repo url
•

Add a computed property for the repo url

•

Modify the template to display the repo url

Go!
v0.5

Template Helpers
•

Build a helper when you want to present data in a
specific way

!
Ember.Handlebars.helper 'from-n...
v0.5

Bower + Moment + Helper

•

Use moment to write a handlebars helper that
displays the relative time

Go!
v0.6

Demo

•

Let's take a look at what we have so far
v0.6

Add the gravatar image

•

Let's add it, shall we?
Components
•

Components combine:
!
!

View
(Events)

+

Controller
(Actions)

!

•

Use them to define reusable pieces of ...
x-spinner
<section class="center">!
{{x-spinner delay=300}}!
</section>!

!

App.XSpinnerComponent = Ember.Component.exten...
Diving Deeper
•

Complex actions

•

Components

•

Events

•

Animations

•

Real-time APIs

•

Authentication
What's Coming for Ember?
•

Ember Conf 2014

•

HTMLbars

•

Build tools and modules

•

Query params to hit release
Resources
•

emberjs.com/guides should be your first stop

•

Smashing Magazine: In-depth Into to Ember

•

Ember Community...
Thanks!
Upcoming SlideShare
Loading in …5
×

Chaione Ember.js Training

1,015 views
909 views

Published on

Slides for a training given at Chaione on Ember.js from February 2014.

https://github.com/aortbals/ember-github-example

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,015
On SlideShare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
9
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Chaione Ember.js Training

  1. 1. Ember.js for Rails Developers Tech Talk - Feb. 21, 2014 Aaron Ortbals
  2. 2. What we’ll be doing • Building a Github Stat Tracker in Ember • Work alone or in pairs • Discuss various aspects of using Ember, Javascript, and their associated ecosystems along the way
  3. 3. You’ll Need • Homebrew • Git ! brew install git! • ! Ruby brew install rbenv ruby-build! rbenv install 2.0.0-p353 # at least 1.9.3! rbenv rehash! gem update --system! gem install bundler rails! • NPM, bower ! brew install node! npm install -g bower! • Clone the repo ! git clone https://github.com/aortbals/ember-github-example! bundle install
  4. 4. Build Tools • A build system: • • prepares them for deployment • • compiles your assets serves them in development Caring about tooling is important
  5. 5. Comparing Toolsets • ember-rails (what we are using)! • • ember-app-kit! • • rake, sprockets, internal REST API, rubygems JS, grunt, npm, bower, ES6 modules ember-appkit-rails! • ember app kit conventions, sprockets, rubygems
  6. 6. Future Build Tools • Broccoli is a build system meant to alleviate many of the issues with grunt (and others) • Goal of building in < 200ms • O(1) build time as the app gets bigger • Ember will likely standardize on this in the core library • Easy transition from Ember App Kit
  7. 7. What's in the repo • I've built a basic Rails 4 API that we can use to consume Github • Turbolinks is removed • Provides a REST API, rake, build system (sprockets), little else • Gives us more time to focus on Ember
  8. 8. What’s in the repo • SCSS • Bourbon: SCSS mixins • Bourbon Neat: semantic grid • Bitters: predefined typography, lists, etc • A basic layout • We will be building some components on top of the basic layout
  9. 9. v0.1 How we’ll work • Checkout a tag and make a practice branch ! git checkout v0.1! git checkout -b practice! • Follow along, look for a when we hit a new tag • We can go back to master and jump to a different step. Stash your changes, commit them, or throw them away ! git reset HEAD --hard! # or `git stash save "my progress"`! # or `git commit`! git checkout master! git checkout v0.2 Tip: List tags! ! git tag -n! ! v0.1 v0.2 Getting started! Step 2
  10. 10. Ember Rails, Releases • Gemfile ! ... gem 'ember-rails' gem 'ember-source', '~> 1.4.0' gem 'ember-data-source', '~> 1.0.0.beta.6’ ... ! • Check http://emberjs.com/builds for the latest releases • Ember has been very stable since 1.0; no breaking changes • Adopted Chrome-style release cycle with semantic versioning
  11. 11. v0.1 Generating Ember Scaffolding • Let's start by using ember-rails to generate our directory structure ! rails generate ember:bootstrap! • Ember App Kit (and EAK-rails) promote JS to the top level - no more nested app/assets/ javascripts/
  12. 12. v0.2 Namespaced API • Let's setup our Rails API and configure Ember ! EmberGithubExample::Application.routes.draw do! get 'app/index'! root to: 'app#index'! ! namespace :api do! # resources :users! # ...! end! ! # Match all remaining paths and direct to Ember! get '*path' => 'app#index'! ...
  13. 13. One view, one controller • app/controllers/app_controller.rb ! class AppController < ApplicationController! def index! end! end! • touch app/views/app/index.html
  14. 14. v0.2 Setup our rails application template • Bundle all templates together thanks to Sprockets • views/layouts/application.html.erb ! <!DOCTYPE html>! <html>! <head>! <title>EmberGithubExample</title>! <%= stylesheet_link_tag "application", media: "all" %>! <%= javascript_include_tag "application" %>! <%= javascript_include_tag "templates/all" %>! <%= csrf_meta_tags %>! </head>! <body>! ! <%= yield %>! ! </body>! </html>! • ! app/assets/javascripts/template/all.js //= require_tree .
  15. 15. v0.2 Configure Ember's namespace • store.js ! EmberGithubExample.ApplicationAdapter = DS.ActiveModelAdapter.extend! namespace: 'api'! ! EmberGithubExample.Store = DS.Store.extend! # Our custom adapter extends `DS.ActiveModelAdapter`! # with a namespace for our API! adapter: 'EmberGithubExample.ApplicationAdapter'
  16. 16. v0.2 Setup the Ember app • application.js.coffee - better logging in dev ! window.EmberGithubExample = Ember.Application.create({! LOG_TRANSITIONS: true,! LOG_ACTIVE_GENERATION: true,! LOG_VIEW_LOOKUPS: true! })! • Sprockets and Rails take care of compiling your app - makes it very easy to get started
  17. 17. v0.2 Let's hello world! • Ember will render the default application.hbs ! <header>Welcome to the Github Stat Tracker!</header>! <section class="app">! </section>! <footer></footer>
  18. 18. v0.2 Using Bower with Rails • Bower is a client-side package manager • Don't vendor stuff. Just don't. • .bowerrc ! {! "directory": "vendor/assets/components"! }! • bower.json ! {! "name": "ember-github-example",! "dependencies": {! "ember-data-extensions": "~1.0.0-beta.7"! }! }! *I blogged about this
  19. 19. v0.2 Ember Data • Makes it easy to retrieve records from the server • Abstracts away the request/response cycle with a robust data model • Provides an ORM-like experience • Works well with Rails • Ember Data is a stable beta
  20. 20. v0.2 Talking with Github • We have a basic REST API to query events for an organization ! localhost:3000/api/events?org=chaione! • See https://developer.github.com/v3/activity/events/
  21. 21. v0.2 Models • A model looks like this: ! App.User = DS.Model.extend!   firstName:  DS.attr('string')!   lastName:   DS.attr('string')!   email:      DS.attr('string')!   username:   DS.attr('string')! company:   DS.belongsTo('company')! createdAt: DS.attr('date')! • Find a user: ! user = App.User.find({ name: "Aaron" })! • belongsTo == hasOne
  22. 22. v0.2 Building some models [ { • Repo • Actor • Org • "type": "Event", "public": true, "payload": { }, "repo": { "id": 3, "name": "octocat/Hello-World", }, "actor": { "login": "octocat", "gravatar_id": "somehexcode", }, "org": { "id": 1, "login": "github", }, "created_at": "2011-09-06T17:26:27Z", "id": "12345" Event - Go! } ]
  23. 23. v0.3 Event EmberGithubExample.Event = DS.Model.extend! type: DS.attr('string')! public: DS.attr('string')! createdAt: DS.attr('date')! actor: DS.belongsTo('actor')! repo: DS.belongsTo('repo')! org: DS.belongsTo('org')! • Models can have relationships • hasMany is supported
  24. 24. v0.3 The Adapter • Ember has what is called 'the adapter' • The adapter is responsible for translating data from a REST API to models • Important to understand when a REST API does not adhere to expected conventions or is not consistent • Ember Rails sets our adapter to DS.ActiveModelAdapter which works out of the box with Rails + ActiveModelSerializers
  25. 25. v0.3 Polymorphic Associations! App.Like = DS.Model.extend! user: DS.belongsTo('user')! likeable: DS.belongsTo('likeable', {polymorphic: true})! ! ! App.Likeable = DS.Model.extend! likes: DS.hasMany('like')! ! ! App.Album = App.Likeable.extend! likes: DS.hasMany('like')! ! ! App.User = DS.Model.extend! likes: DS.hasMany('like')
  26. 26. v0.4 Router • Ember represents each of the possible states in your application as a URL ! interacts event ! • The user can use the back button • Avoids losing state • If you hit refresh and the state changes, then 😂
  27. 27. v0.4 Router Example ! • Static routes ! • Resource routes • Nested resources App.Router.map (match) ->!   @route 'app', { path: '/'}!   @route 'login'!   @route 'signup'!  !   @resource 'users', ->!     @route 'new'!     @resource 'user',!       path: ':user_id'!  !   @resource 'albums', ->!     @route 'new'!   @resource 'album',!     path: '/album/:album_id'!
  28. 28. v0.4 A route • Each route has a route handler • It finds the model, hands it to the controller, and renders a template ! App.UsersRoute = Ember.Route.extend   model: ->     App.User.find()   App.UsersNewRoute = Ember.Route.extend   model: ->     App.User.createRecord()   App.SignupRoute = App.UsersNewRoute
  29. 29. v0.4 Declare our route • https://api.github.com/orgs/chaione/events ! EmberGithubExample.Router.map ()->! @resource 'org', { path: '/orgs/:orgName' }, ->! @resource 'events'! ! ! # Use the browser history API! EmberGithubExample.Router.reopen! location: 'history'
  30. 30. v0.4 Event Route • A Route provides a model hook ! EmberGithubExample.EventsRoute = Ember.Route.extend! model: (params) ->! orgName = @modelFor('org').orgName! return [] unless orgName # No results! ! @store.find('event', { org: orgName }) Route: @resource 'org', { path: '/orgs/:orgName' }, ->! @resource 'events'!
  31. 31. v0.4 Event Template • Ember uses Handlebars which wraps {{things}} in curly braces ! <div class="main">! <div class="image"></div>! <div class="text">! <div class="title">{{type}} by {{actor.login}}</div>! <div class="sub-title">! <span class="point">{{createdAt}}</span>! <span class="point">{{repo.name}}</span>! </div>! </div>! </div>!
  32. 32. v0.4 Events Template • In the events template we loop over the route model ! <section class="results">! {{#each model}}! {{partial "event"}}! {{/each}}! </section>
  33. 33. v0.4 Controllers handle actions • Controllers handle actions on your current view • • form submissions, clicks, etc They can also decorate the model with computed properties
  34. 34. v0.4 Events Controller EmberGithubExample.ApplicationController = Ember.Controller.extend! queryField: null! actions:! search: ->! if @get('queryField')! @transitionTo('events', @get('queryField'))! ! ! EmberGithubExample.EventsController = EmberGithubExample.ApplicationController.extend({})!
  35. 35. v0.4 What do we have so far? • Models - represent our data from the server • Router - declared route for our URL • Route - hand the results data to our controller and template • Events Template - loop over the results • Event Template - present the event data
  36. 36. v0.5 Computed Properties App.Person = Ember.Object.extend! firstName: null! lastName: null! ! fullName: (->! "#{@get('firstName')} #{@get('lastName')}"! ).property('firstName', 'lastName')! ! ! aaron = App.Person.create! firstName: "Aaron"! lastName: "Ortbals"! ! aaron.get('fullName') # Aaron Ortbals
  37. 37. v0.5 Add the repo url • Add a computed property for the repo url • Modify the template to display the repo url Go!
  38. 38. v0.5 Template Helpers • Build a helper when you want to present data in a specific way ! Ember.Handlebars.helper 'from-now', (date) ->! return unless date! moment(date).fromNow()! ! ! <span>{{from-now createdAt}}</span>!
  39. 39. v0.5 Bower + Moment + Helper • Use moment to write a handlebars helper that displays the relative time Go!
  40. 40. v0.6 Demo • Let's take a look at what we have so far
  41. 41. v0.6 Add the gravatar image • Let's add it, shall we?
  42. 42. Components • Components combine: ! ! View (Events) + Controller (Actions) ! • Use them to define reusable pieces of UI + behavior in your application
  43. 43. x-spinner <section class="center">! {{x-spinner delay=300}}! </section>! ! App.XSpinnerComponent = Ember.Component.extend({! lines : 12, // The number of lines to draw! ...! ! ! ! inserted: function() {! this._showSpinner();! }.on('didInsertElement'),! teardown: function() {! this.spinner.stop();! }.on('willDestroyElement'),! _showSpinner: function() {! var target = this.get('element');! this.spinner = new Spinner({ ... });! this.spinner.spin(target);! },! });! ! Ember.Handlebars.helper('x-spinner', App.XSpinnerComponent);
  44. 44. Diving Deeper • Complex actions • Components • Events • Animations • Real-time APIs • Authentication
  45. 45. What's Coming for Ember? • Ember Conf 2014 • HTMLbars • Build tools and modules • Query params to hit release
  46. 46. Resources • emberjs.com/guides should be your first stop • Smashing Magazine: In-depth Into to Ember • Ember Community Twitter List • My Ember bookmarks
  47. 47. Thanks!

×