Riding the Rails, the Rich Internet Way
Here is the sample that I showed at OSCON, a bit updated on the plane flight home, of how ActionStep could integrate simply with Rails.
You can find notes from the OSCON session here.
First we start with requiring actionstep in our application.rb file:
require "actionstep"
Simple enough, now we build a basic controller:
class WindowController < ApplicationController def window @title = "Welcome to OSCON" render end end
It just sets the title instance variable and then you build a asv (ActionStepView) formatted file which describes your ActionStep UI:
NSWindow :main do attributes :title => @title, :contentRect => {:x => 100, :y => 50, :width => 400, :height => 400} execute { application.load(:view1) } end
A couple of things to note about this. First, the @title is reference just like when using Builder to build XML with Ruby, but here you specify component types (NSWindow) and provide them with an (optional) name (:main). You set the attributes, and then embed this cool execute block. That block is deceptively powerful. In that block you have a root object, with ‘application’ being the application control object, and then you just do dot (.) method invocation and you can pass parameters, and chain the call (root.foo.bar) and that code is actually executed dynamically in ActionStep when it loads the component definition. That example loads an additional component definition (:view1) into the NSWindow component. That in turn calls the view1_controller.rb file:
class View1Controller < ApplicationController def hello puts "YOU SELECTED PERSON: #{@params["selected_person_id"]}" end def view1 @names = {"Richard"=>2, "James"=>4, "Dave"=>3} @buttons = ["H1", "H2", "H3", "Sy"] render end end
Which defines a method (hello) and a rendering method (view1) which sets one variable to be a Ruby hash, and another to be a Ruby array then loads the view1.asv file:
NSView :test do attributes :rect => {:x => 0, :y => 0, :width => 200, :height => 400}, :backgroundColor => 0xdddd00 publishes :selected_person_id => execute { names.selectedItem.label } NSButton :hello do attributes :title => "Test", :rect => {:x => 10, :y => 10, :width => 20, :height => 20} end ASList :names do attributes :items => @names, :rect => {:x => 10, :y => 50, :width => 100, :height => 200} end end
Still with me? Cool! This file has lots of nifty things. You have an NSView with has two other components in it (NSButton, NSList). You set the attributes of those controls and name them (:hello, :names). When the template system parses the asv files encounters a component of a given name, it reflects on the controller instance to determine if that name has a corresponding method, which in the case of the NSButton named :hello there is a hello method on View1Controller. That in turn sets the target/action on the button to call that method (via HTTP) when the user clicks on the button. The other piece is the publishes hash. What that does is indicate a named variable that will be published when an action is called (the user clicks on the :hello NSButton). When that occurs, the execute block is called dynamically in ActionStep the root object here being the list (names) and invokes the selectedItem.label methods, returning the currently selected user from the list. Looking back at the View1Controller ‘hello’ method, its referenced just like with any other HTTP param:
def hello puts "YOU SELECTED PERSON: #{@params["selected_person_id"]}" end
This is just a basic example, but I have all the pieces build to make this work. I am now working on what is returned from the hello method (like an ‘execute’ block) which would provide for a work flow with round tripping of data and actions. Once that is done I will publish this out a gem for folks to play with.
projects/actionstep/rails.txt · Last modified: 2007/02/19 08:15 by niko