Flexonrails Derailed Talk

24
Daniel Wanja Tony Hillerson

description

Slides from the talk, demoing the source code from out Flex on Rails book, given on January 22nd at Derailed (the Denver Ruby on Rails user group). Source code is available on http://flexonrails.com

Transcript of Flexonrails Derailed Talk

Page 1: Flexonrails Derailed Talk

Daniel WanjaTony Hillerson

Page 2: Flexonrails Derailed Talk

We wrote a book!

• Yea, us!

• What the heck?

Page 3: Flexonrails Derailed Talk

Why Flex on Rails?

• You already know “why Rails?”

• Flex is another tool in the toolbox

• Service oriented

Page 4: Flexonrails Derailed Talk

Agenda

• A bit about Flex

• Highlights and source from the book

• Drinking

Page 5: Flexonrails Derailed Talk

Flex is...

• Part of Adobe’s Flash platform

• Open Source (framework) and free

Page 6: Flexonrails Derailed Talk

Flex is...

• A compiler

• An XML language - MXML

• A set of components

Page 7: Flexonrails Derailed Talk

Flex ...

• A way to write ActionScript declaratively

• Compiles to ActionScript

• ActionScript -> SWF

• Runs in the Flash Player

Page 8: Flexonrails Derailed Talk

Flex on Rails

• Compiled source - keep separate

• SWF -> /public during deployment

• Flex talks to Rails withXML, JSON, or AMF

Page 9: Flexonrails Derailed Talk

Development Workflow

• Open SWF or HTML Wrapper from Public

• HTML Wrapper - can use relative urls

• SWF - Hardcode localhost:3000 :-(

• Either - Load an url from config :-)

Page 10: Flexonrails Derailed Talk

[email protected]:danielwanja/flexonrails.git

• Passing Data with XML• RESTful Services• Passing Data with AMF• Data Visualization• Building Flex with Rake• Read the Source!• Observers in Flex• Authentication• Hierarchical Data With AMF• Advanced Data Grid with Awesome Nested Set• Server Push with Juggernaut• Flex and Javascript• File Upload

Page 11: Flexonrails Derailed Talk

Passing Data with XML

Rails Person.new(:first_name => 'daniel', :last_name => 'wanja').to_xml

Flexvar person:XML = <person><first_name>tony</first_name><last_name>hillerson</last_name></person>

Getting XML to

Flex

<mx:HTTPService id="index" url="http://localhost:3000/people.xml" resultFormat="e4x" />

index.send()

Sending XML to

Rails

<mx:HTTPService id="update" url="http://localhost:3000/people/{id}.xml?_method=put" contentType="application/xml" resultFormat="e4x" method="POST" result="index.send()" />

update.send(person) 02

Page 12: Flexonrails Derailed Talk

RESTful ServicesHTTP verb URL Controller

GET /accounts/:account_id/positions {:action=>"index", :controller=>"positions"}

POST /accounts/:account_id/positions {:action=>"create", :controller=>"positions"}

GET /accounts/:account_id/positions/:id {:action=>"show", :controller=>"positions"}

PUT /accounts/:account_id/positions/:id {:action=>"update", :controller=>"positions"}

DELETE /accounts/:account_id/positions/:id {:action=>"destroy", :controller=>"positions"}

03

Page 13: Flexonrails Derailed Talk

Nested Resources

/accounts/:id

/accounts/:account_id/positions/:id

/accounts/:account_id/positions/:position_id/movements/:id

class Account < ActiveRecord::Base has_many :positions, :dependent => :destroyend

class Position < ActiveRecord::Base belongs_to :account has_many :movements, :dependent => :destroyend

class Movement < ActiveRecord::Base belongs_to :positionend

Page 14: Flexonrails Derailed Talk

Data Visualization

07

Page 15: Flexonrails Derailed Talk

Authentication

• All Flex service calls go through the browser

• AIR manages cookies

• = Standard cookie based credentials work fine

Page 16: Flexonrails Derailed Talk

Hierarchical Data with AMF

• Works nicely with Awesome Nested Set

• Good for retrieving Object Graphs

• More work when sending Object Graphs

Page 17: Flexonrails Derailed Talk

Read the Source!

• Flex source is available in Flex Builder

• MXML is compiled to ActionScript

Page 18: Flexonrails Derailed Talk

Observers in Flex

• Binding is sweet

• {} notation

• BindingUtils

• ChangeWatcher

Page 19: Flexonrails Derailed Talk

Building Flex with Rake

• Simple shell command to mxmlc

• mxmlc needs to be in the path

Page 20: Flexonrails Derailed Talk

Flex and Javascript

• HTML *and* Flex is sometimes the right answer

• Flex Ajax Bridge

• ExternalInterface

Page 21: Flexonrails Derailed Talk

Advanced Data Grid with Awesome Nested Set

class Category < ActiveRecord::Base acts_as_nested_set def full_xml(builder=nil) xml = builder ||= Builder::XmlMarkup.new(:indent => 2) xml.category(:id => id, :name => name, :description => description, :qty_in_stock => qty_in_stock) do children.each { |child| child.full_xml(xml) } end end end

<mx:HTTPService id="categories" url="http://localhost:3000/categories" resultFormat="e4x" />

18

Page 22: Flexonrails Derailed Talk

Server Push with Juggernaut

JuggernautPush Server

2. send_to_channels

1.

po

st

to http://

localhost:3000/

messenger/

message

3.

pu

sh

JS

ON

m

essa

ge

to

so

cke

t

3. p

ush

JSO

N

mes

sage

to s

ocke

t

Rails Application

20

Page 23: Flexonrails Derailed Talk

Server Push with Juggernaut

JuggernautPush Server

2. send_to_channels

1. post to

http://

localhost:3000/

messenger/

message

3. push J

SO

N

message to s

ocket

3. p

ush

JSO

N

mes

sage

to s

ocke

t

Rails Application

class MessengerController < ApplicationController def message data = {:user => params[:user], :message => params[:message]} Juggernaut.send_to_channel(data, :im_channel) render :nothing => true endend

<mx:HTTPService id="sendMessage" url="http://localhost:3000/messenger/message" method="POST" result="msg.text=''" fault="mx.controls.Alert.show(event.fault.faultString);"> <mx:request xmlns=""> <user>{user.text}</user> <message>{msg.text}</message> </mx:request></mx:HTTPService>

<net:XMLSocket id="socket" connect="connectHandler(event)" data="dataHandler(event)" close="closeHandler(event)" ioError="ioErrorHandler(event)" securityError="securityErrorHandler(event)" /> socket.connect(hostName, port);

Page 24: Flexonrails Derailed Talk

File Upload

<net:FileReference id="fileReference" select="selectHandler(event)" />

private function selectHandler(event:Event):void { var request:URLRequest = new URLRequest("http://localhost:3000/assets") var uploadDataFieldName:String = 'asset[uploaded_data]' fileReference.upload(request, uploadDataFieldName);}

class Asset < ActiveRecord::Base has_attachment :storage => :file_systemend

class AssetsController < ApplicationController def create @asset = Asset.new(params[:asset]) if @asset.save render(:nothing => true, :status => 200) else render(:nothing => true, :status => 500) end endend

22