Flex With Rubyamf

39
Flex and Rails with RubyAMF Tony Hillerson Software Architect EffectiveUI RailsConf

description

Slides for my RailsConf 09 talk on RubyAMF and Rails

Transcript of Flex With Rubyamf

Page 1: Flex With Rubyamf

Flex and Rails with RubyAMF

Tony HillersonSoftware ArchitectEffectiveUIRailsConf

Page 2: Flex With Rubyamf

Code and Slides:http://github.com/thillerson/preso_code/

Page 3: Flex With Rubyamf

Sample du Jour: Stuff

Page 4: Flex With Rubyamf
Page 5: Flex With Rubyamf

Why Flex and Rails?

They Make The Great Tag Team!

Page 6: Flex With Rubyamf

[SKIP INTRO]

Page 7: Flex With Rubyamf

What are the Options?

Page 8: Flex With Rubyamf

XML

Page 9: Flex With Rubyamf

XML is the Default Option

Page 10: Flex With Rubyamf

# POST /contexts# POST /contexts.xmldef create @context = Context.new(params[:context]) respond_to do |format| if @context.save flash[:notice] = 'Context was successfully created.' format.html { redirect_to(@context) } format.xml { render :xml => @context, :status => :created, :location => @context } else format.html { render :action => "new" } format.xml { render :xml => @context.errors, :status => :unprocessable_entity } end endend

Page 11: Flex With Rubyamf

JSON

Javascript Object Notation

Page 12: Flex With Rubyamf

JSON is in Rails Tooformat.json { render :json => @context.to_json }

http://as3corlib.googlecode.com

var obj:Object = JSON.decode(jsonString)

Page 13: Flex With Rubyamf

AMF

Action Message Format

Page 14: Flex With Rubyamf

AMF is the Good Stuff

Buck Thinks it’s Great!

Page 15: Flex With Rubyamf

RubyAMF

http://rubyamf.orghttp://rubyamf.googlecode.com

Page 16: Flex With Rubyamf

Installing RubyAMF$ script/plugin install http://rubyamf.googlecode.com/svn/current/rubyamf

• New File: app/controllers/rubyamf_controller.rb• New File: config/rubyamf_config.rb• config/initializers/mime_types.rb modified: Mime::Type.register "application/x-amf", :amf• config/routes.rb modified: ActionController::Routing::Routes.draw do |map| map.rubyamf_gateway 'rubyamf_gateway', :controller => 'rubyamf', :action => 'gateway' end

Page 17: Flex With Rubyamf

Con"guring RubyAMFmodule RubyAMF module Configuration ClassMappings.translate_case = true ClassMappings.assume_types = false ParameterMappings.scaffolding = true ClassMappings.register( :actionscript => 'Task', :ruby => 'Task', :type => 'active_record', #:associations => ["context"], :attributes => ["id", "label", "context_id", "completed_at", "created_at", "updated_at"]) endend

Page 18: Flex With Rubyamf

Con"guring RubyAMFClassMappings.translate_case = false

public var created_at:Date;

ClassMappings.translate_case = true

public var createdAt:Date; // created_at in rails

Page 19: Flex With Rubyamf

Con"guring RubyAMFClassMappings.assume_types = true

class Context < ActiveRecord::Base

[RemoteClass(alias="Context")]public class Context {

matches

for free

Page 20: Flex With Rubyamf

Con"guring RubyAMFClassMappings.assume_types = false

class Context < ActiveRecord::Base

[RemoteClass(alias="Context")]public class Context {

matches

ClassMappings.register( :actionscript => 'Context', :ruby => 'Context', :type => 'active_record', :attributes => ["id", ...])

with registration

Page 21: Flex With Rubyamf

Con"guring RubyAMFParameterMappings.scaffolding = false

save(context);def save @context = params[0]becomes

ParameterMappings.scaffolding = true

save( {context:context});

def save @context = params[:context]becomes

Page 22: Flex With Rubyamf

Connecting to Rails via RubyAMF

<mx:RemoteObject id="contextsService" destination="rubyamf" endpoint="http://localhost:3000/rubyamf_gateway/" source="ContextsController" showBusyCursor="true"/>public function save(context:Context):void { var call:AsyncToken =

contextsService.save({context:context}); call.addResponder(responder);}

Page 23: Flex With Rubyamf

Development Work#ow

Page 24: Flex With Rubyamf

1. Generate and Migrate$ script/generate rubyamf_scaffold context label:string

$ rake db:migrate

class CreateContexts < ActiveRecord::Migration def self.up create_table :contexts do |t| t.string :label t.timestamps end end

def self.down drop_table :contexts endend

Page 25: Flex With Rubyamf

def load_all @contexts = Context.find :all respond_to do |format| format.amf { render :amf => @contexts } end end def save respond_to do |format| format.amf do if params[:context].save render :amf => params[:context] else render :amf =>

FaultObject.new(params[:context].errors.join("\n")) end end end end

Page 26: Flex With Rubyamf

2. Sample Datawork: id: 1 label: Work

home: id: 2 label: Home

anarco_syndicalist_commune_biweekly_meetings: id: 3 label: Anarcho-syndicalist Commune Bi-weekly Meetings

Page 27: Flex With Rubyamf

3. Test

class ContextTest < ActiveSupport::TestCase def test_context_without_label_fails non_label_context = Context.new assert !(non_label_context.save) error_messages = non_label_context.errors.on(:label) assert !(error_messages.empty?) end

class Context < ActiveRecord::Base validates_presence_of :label

Page 28: Flex With Rubyamf

4. Con"gure

ClassMappings.register( :actionscript => 'Context', :ruby => 'Context', :type => 'active_record', #:associations => ["tasks"], :attributes => ["id", "label", "created_at", "updated_at"])

Page 29: Flex With Rubyamf

5. Wire<mx:RemoteObject id="contextsService" destination="rubyamf" endpoint="http://localhost:3000/rubyamf_gateway/" source="ContextsController" showBusyCursor="true"/>

<mx:RemoteObjectid="tasksService"

destination="rubyamf" endpoint="http://localhost:3000/rubyamf_gateway/" source="TasksController" showBusyCursor="true"/>

Page 30: Flex With Rubyamf

5. Wirepublic function loadAll():void { var call:AsyncToken = service.load_all(); call.addResponder(responder);}

public function save(context:Context):void { var call:AsyncToken =

service.save({context:context}); call.addResponder(responder);}

public function destroy(context:Context):void { var call:AsyncToken =

service.destroy({id:context.id}); call.addResponder(responder);}

Page 31: Flex With Rubyamf

5. Wirepublic function execute(event:CairngormEvent):void { var evt:SaveContextEvent = event as SaveContextEvent; var delegate:ContextsDelegate = new ContextsDelegate(this); delegate.save(evt.context);}

public function result(data:Object):void { var result:ResultEvent = data as ResultEvent; var context:Context = result.result as Context; ...}

Page 32: Flex With Rubyamf

X. Rinse and Repeat

Page 33: Flex With Rubyamf

The Future

Page 34: Flex With Rubyamf

GemPlugin + GemC Extension

Page 35: Flex With Rubyamf

GemPlugin

C Extension

Page 36: Flex With Rubyamf
Page 37: Flex With Rubyamf

An Impassioned Plea

Page 39: Flex With Rubyamf

Thanks!Tony Hillersonhttp://slideshare.com/thillersonhttp://github.com/thillersonhttp://thillerson.blogspot.comhttp://effectiveui.com

Twitter: thillersonBrightkite: thillerson

39

You

YourFather

Bob