<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>OnRails.org: Tag ActiveRecord</title>
    <link>http://onrails.org/articles/tag/activerecord?tag=activerecord</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Ruby On Rails and related matters.</description>
    <item>
      <title>Part 1: Using WebORB to access ActiveRecords from a Flex application.</title>
      <description>On Friday I started for a customer an investigation in providing a Flex front-end for an Ruby on Rails backend using WebORB. In parallel I will push this investigation further for myself in order to find a nice mechanisms to support &lt;span class="caps"&gt;CRUD&lt;/span&gt; operations with relationship support using WebORB. Over the next couple of weeks I will write some of my findings on this blog. So this week-end I started to put in place an environment where I can unit test the interaction between Flex and Ruby on Rails using WebORB. In this first part I will show how to extend WebORB to perform a deep find, how to write a Flex unit test to test asynchronous remote calls, and how to use  Ruby on Rails fixtures  for the Flex unit tests.
&lt;p/&gt;
This is an extract of the &amp;#8216;final&amp;#8217; version of the Flex unit test (as of Part 1 of the article). The full version is at the end of the article. 
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;public function testGetFirstCustomer():void {
    var activeRecordService:RemoteObject = getActiveRecordService(onGetFirstCustomerResult); 
    create_fixtures([&amp;quot;customers&amp;quot;, &amp;quot;addresses&amp;quot;, &amp;quot;orders&amp;quot;, &amp;quot;items&amp;quot;], doGetCustomerFirstCustomer, activeRecordService);
}          
private function doGetCustomerFirstCustomer(activeRecordService:Object):void {
    var options:Object = {'include':['bill_to_address', {'orders':'items'}]};
    activeRecordService.get(&amp;quot;Customer&amp;quot;, 1, options);                       
}
private function onGetFirstCustomerResult(event:Event, token:Object=null):void 
{
    assertTrue(event.toString(), event is ResultEvent); // First param is message.
    var customer:Object = ResultEvent(event).result;
    assertEquals(&amp;quot;Daniel&amp;quot;, customer.name);
    assertEquals(&amp;quot;Littleton&amp;quot;, customer.bill_to_address.city);
    assertEquals(2, customer.orders.length);    // 2 order
    assertEquals(3, customer.orders[0].items.length); // the first has 3 items
    assertEquals(&amp;quot;Remote Control&amp;quot;, customer.orders[0].items[2].product); 
}          
          &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2&gt;Introduction&lt;/h2&gt;
There are several ways a Flex front-end can connect to a Rails application: via a RESTFul services (xml over html),  via &lt;span class="caps"&gt;SOAP&lt;/span&gt;, and now also using  WebORB from Midnight Coders (see http://www.themidnightcoders.com/weborb/rubyonrails/index.htm). WebORB for Ruby on Rails is a server-side technology enabling connectivity between Flex and Flash Remoting clients and Ruby on Rails applications.  WebORB and Flex provides an efficient way of encoding and decoding data using a binary protocol named &lt;span class="caps"&gt;AMF3&lt;/span&gt; (Actionscript Message Format (I think)). This format is recognized by the Flash Player and provides an efficient way to communicate between a Flex application and a Ruby On Rails server.
&lt;/p&gt;

&lt;p&gt;
This article will only investigate the WebORB usage, and we will not look into using &lt;span class="caps"&gt;SOAP&lt;/span&gt; or a RESTFul api. Part 1 of the article will show how to setup the Rails and the Flex applications to use WebORB, and how to retrieve data from the server. In subsequent parts of this article, I will comment my findings regarding updating data, security and performance issues and other aspect I discover during my investigation.
&lt;/p&gt;

&lt;p&gt;
As you may not know, with Lee we wrote a similar server-side technology 18 months ago (flexonrails.com) which was based on &lt;span class="caps"&gt;AMF4R&lt;/span&gt;, but we where not satisfied with our findings at that time, nor with the qualitify of one of the library we where using, and the demand for integrating Flex and Ruby On Rails was non existent at that time, certainly due to the high price tag of Flex and the fact that not many developers were interested in both of these technologies as Flex was geared towards the enterprise and RoR was an open source framework. Since then Flex is free (not FlexBuilder, nor the DataServices), but everything we do in this article can be developed and deployed using free tools. Also Adobe is pushing quite hard to appeal to the open source community.  I started this project using FlexBuilder for Mac, but I will also show how to compile the samples and tests using the flex command line compiler (mxmlc). 
&lt;/p&gt;

&lt;p&gt;
To download WebORB and to set it up I am following the instructions of http://www.themidnightcoders.com/weborb/rubyonrails/gettingstarted.htm. So for more details go see  www.themidnightcoders.com
&lt;/p&gt;

&lt;p&gt;
For this article I will create a &amp;#8220;fictional&amp;#8221; application. For my customer I am directly integrating with the existing application. In fact using this fictional application will allow me to test the WebORB in many different ways. Note that my customers current front-end application is really cool. It  is written in plain-old Rails, aka Ajax, html, css, rjs. Nevertheless we wanted to investigate if we can achieve similar functionality with less code using Flex and to identify the cost and benefits of such a development. I will spend a couple of days over the next weeks for this investigations.
&lt;/p&gt;

&lt;h2&gt;These are the steps I followed for this article&lt;/h2&gt;
&lt;pre&gt;
1. Create a Rails app and add the WebORB plugin
2. Write a simple unit test to access some data using a RemoteObject 
    a. create the Flex application using FlexBuilder.
         b. create the Customer ActiveRecord
         c. Write the FlexUnit test
    d. Write a small script to compile a Flex app from the command prompt.
         e. make the test pass.
3 . Use fixtures
4. Create a model (db+active record)
5. Write a test to retrieve the model
6. Provide a way to use fixtures from FlexUnit, so we can do some more testing.&lt;/pre&gt;

&lt;h2&gt;1. Create a Rails app and add the WebORB plugin&lt;/h2&gt;

* Go to the folder where you want create your rails application and issue the following command:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;    rails rails&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p/&gt;
This create the rails application in a folder named &amp;#8220;rails&amp;#8221;. You can choose any name you want i.e. rails myApp. Note we use rails 1.1.6 for this article.
&lt;p/&gt;

* Cd to the root of you rails application and install the plugin. The following command installs the plugin files in the vendor/plugins/weborb folder.
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;./script/plugin install http://themidnightcoders.net:8089/svn/weborb&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;2. Write a simple unit test to access some data using a RemoteObject&lt;/h2&gt;

	&lt;p&gt;We will put the flex applications in a folder named &amp;#8220;flex&amp;#8221; and put this folder next to the &amp;#8220;rails&amp;#8221; folder we create just before. Now lets download FlexUnit from http://weblogs.macromedia.com/as_libraries/zips/flexunit.zip. See Adobes wiki for more information (http://labs.adobe.com/wiki/index.php/ActionScript_3:resources:apis:libraries#FlexUnit)&lt;/p&gt;


&lt;h3&gt;2.a) Creating a project in FlexBuilder&lt;/h3&gt;

*  Create a FlexBuilder project (select Flex Data Services)&lt;br/&gt;
Root Folder: /Users/daniel/MyStuff/Projects/WebORBInvestigation/rails/config&lt;br/&gt;
Root Url: http://localhost.com:3000/weborb/&lt;br/&gt;
&lt;p/&gt;

Root Folder points to your Rails application config folder&lt;br/&gt;
Root Url points to the weborb controller.&lt;br/&gt;
&lt;p/&gt;

*  In the project properties set&lt;br/&gt;
Output folder: /Users/daniel/MyStuff/Projects/WebORBInvestigation/rails/public/flex&lt;br/&gt;
Output folder &lt;span class="caps"&gt;URL&lt;/span&gt;: http://localhost:3000/flex&lt;br/&gt;
&lt;p/&gt;

	&lt;ul&gt;
	&lt;li&gt; Add the flexunit.swc (in the /bin folder of the FlexUnit downloads). A .swc is the compiled version of the FlexUnit framework.&lt;/li&gt;
	&lt;/ul&gt;


&lt;h3&gt;2.b) create the Customer ActiveRecord&lt;/h3&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;    ./script/generate model Customer&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;pre&gt;
This generate the following files:
      exists  app/models/
      exists  test/unit/
      exists  test/fixtures/
      create  app/models/customer.rb
      create  test/unit/customer_test.rb
      create  test/fixtures/customers.yml
      create  db/migrate
      create  db/migrate/001_create_customers.rb
&lt;/pre&gt;
Now edit db/migrate/001_create_customers.rb as follows:

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;CreateCustomers&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ActiveRecord&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Migration&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;self.up&lt;/span&gt;
    &lt;span class="ident"&gt;create_table&lt;/span&gt; &lt;span class="symbol"&gt;:customers&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;t&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
      &lt;span class="ident"&gt;t&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;column&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;name&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:string&lt;/span&gt;
      &lt;span class="ident"&gt;t&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;column&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;address&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:string&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;self.down&lt;/span&gt;
    &lt;span class="ident"&gt;drop_table&lt;/span&gt; &lt;span class="symbol"&gt;:customers&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

Now make sure you created an empty database and you point to it in the config/database.yml file. Then create the customers table by typing the following command:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;    rake migrate&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

Now let&amp;#8217;s create two customers:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;./script/console
&amp;gt;&amp;gt; Customer.create(:name =&amp;gt; &amp;quot;Daniel&amp;quot;, :address =&amp;gt; &amp;quot;Denver&amp;quot;) 
&amp;gt;&amp;gt; Customer.create(:name =&amp;gt; &amp;quot;Samuel&amp;quot;, :address =&amp;gt; &amp;quot;Geneva&amp;quot;)
&amp;gt;&amp;gt; exit&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;2.c) Write a flex unit test&lt;/h3&gt;

One of the issues with Flash and Flex unit testing of remote calls is the asynchronous nature of the remote calls. FlexUnit was based on JUnit and was mainly created for synchronous call testing. On one large project we dealt with this issue by splitting each test in two phases. The first phase performing calls and collecting data, we called it CallSequence, and the second phase to test the returned data. Since then, FlexUnit was extended with a nice feature allowing to test asynchronous calls. Look for the usage of the TestCase.addAsync method. It allows to notify that the current test method is waiting for a callback.
&lt;p/&gt;

	&lt;p&gt;With this knowledge in mind let&amp;#8217;s dive into writing the test. We want to retrieve the list of customers, ensure that their are two customers, and verify the name off one of the customers. This is what the test looks like:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;div class="codetitle"&gt;WebORBReadOnlyTest.as&lt;/div&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;package {
     import flexunit.framework.TestCase;
    import mx.rpc.remoting.RemoteObject;
    import flash.events.Event;
    import mx.rpc.events.ResultEvent;
    import mx.rpc.events.FaultEvent;     

     public class WebORBReadOnlyTest extends TestCase {

          public function WebORBReadOnlyTest( methodName:String = null ) {
               super( methodName );
        }

        // This method triggers a remote call and defines the event handler for the asynchronous response.
          public function testGetCustomerList():void {
              var asyncCall:Function = addAsync(onCustomerListResult, 1000);
             var dataService:RemoteObject = new RemoteObject();   
            dataService.destination = &amp;quot;DataService&amp;quot;; // Default WebORB ActiveRecord accessor 
            dataService.addEventListener(&amp;quot;result&amp;quot;, asyncCall);
            dataService.addEventListener(&amp;quot;fault&amp;quot;, asyncCall);
             dataService.list(&amp;quot;Customer&amp;quot;);        
           }          
           // This is the even handler trigger by the asynchronous response, let assert that we received what we expected.
        private function onCustomerListResult(event:Event, token:Object=null):void 
        {
            assertTrue(event is ResultEvent); 
            var data:Object = ResultEvent(event).result;
            assertEquals(2, data.length);
            assertEquals(&amp;quot;Daniel&amp;quot;, data[0].name);
        }

      }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;We also need a test runner&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;div class="codetitle"&gt;WebORBTestApp.mxml&lt;/div&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;
&amp;lt;mx:Application xmlns:mx=&amp;quot;http://www.adobe.com/2006/mxml&amp;quot; 
    layout=&amp;quot;absolute&amp;quot;
                xmlns:flexunit=&amp;quot;flexunit.flexui.*&amp;quot;
                creationComplete=&amp;quot;runTests()&amp;quot;&amp;gt;
    &amp;lt;mx:Script&amp;gt;
        &amp;lt;![CDATA[
            import flexunit.framework.TestSuite;

            private function runTests():void
            {
                 var ts:TestSuite = new TestSuite();                 
                 ts.addTestSuite( WebORBReadOnlyTest );                 
                testRunner.test = ts;
                testRunner.startTest();
             }
        ]]&amp;gt;
    &amp;lt;/mx:Script&amp;gt;

    &amp;lt;!-- flexunit provides a very handy default test runner GUI --&amp;gt;
    &amp;lt;flexunit:TestRunnerBase id=&amp;quot;testRunner&amp;quot; width=&amp;quot;100%&amp;quot; height=&amp;quot;100%&amp;quot; /&amp;gt;

&amp;lt;/mx:Application&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;2.d) Compile the unit test&lt;/h3&gt;

	&lt;p&gt;The following script compiles the application from the command line (on &lt;span class="caps"&gt;OSX&lt;/span&gt;). That is, not using FlexBuilder. You may need to adapt for your needs. On windows it may be easier and you can maybe just refer to the mxmlc.exe. Not that I had to patch the flex-config file due to an compilation issue due to some missing fonts. You can try without the patch first. Let me know if that worked.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;div class="codetitle"&gt;build.sh&lt;/div&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;FLEX_HOME=&amp;quot;/Applications/Adobe Flex Builder 2 Beta/Flex SDK 2/&amp;quot;
cp flex-config-patched.xml &amp;quot;$FLEX_HOME/frameworks/&amp;quot;
java -Xmx384m -Dsun.io.useCanonCaches=false -jar &amp;quot;$FLEX_HOME/lib/mxmlc.jar&amp;quot; -load-config &amp;quot;$FLEX_HOME/frameworks/flex-config-patched.xml&amp;quot;  -library-path+=../flexunit/bin/flexunit.swc WebORBTestApp.mxml
cp WebORBTestApp.swf ../../rails/public/flex &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;2.e) Run the unit test&lt;/h3&gt;

	&lt;p&gt;Make sure the server is running and launch the flex test application. &lt;br/&gt;&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://onrails.org/files/TestRunner.gif"/&gt;&lt;/p&gt;


&lt;p/&gt;

Note that I had some red bars before I got the test to pass, but I wanted to spare these details.
&lt;p/&gt;

	&lt;p&gt;Ok, this is quite some work just do test the dataService.list(&amp;#8220;Customer&amp;#8221;) call. However now I have an environment which I can use to go crazy on testing various aspects of the Flex and Ruby On Rails integration using WebORB.&lt;/p&gt;


&lt;h2&gt;3 . Extend WebORB to allow to write a FlexUnit test using fixtures&lt;/h2&gt;

	&lt;p&gt;Without fixtures this test wouldn&amp;#8217;t be very useful. We need a way to reset the fixtures between each test method invocation.&lt;/p&gt;


&lt;h3&gt;3.a) First let&amp;#8217;s add a mechanism to reset the fixtures using WebORB&lt;/h3&gt;

	&lt;p&gt;create the app/services/ActiveRecordService.rb file (note this is the naming convention for the WebORB services, I would rather use active_record_service.rb but I haven&amp;#8217;t tried if that works.)&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;weborb/context&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;active_record/fixtures&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;ActiveRecordService&lt;/span&gt; 
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;create_fixtures&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;table_names&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="constant"&gt;Fixtures&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;create_fixtures&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="expr"&gt;#{RAILS_ROOT}&lt;/span&gt;/test/fixtures/&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="ident"&gt;table_names&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;{})&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt; 
&lt;span class="keyword"&gt;end&lt;/span&gt;    &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

ActiveRecordService is the placeholder where we will extend the standard WebORB DataService offering, by adding some utility methods to reset the fixtures and by providing an extended get method as described further in this document.
&lt;p/&gt;

	&lt;p&gt;Now configure WebORB to recognize this new service. Add the following code to the config/WEB-INF/flex/remoting-config.xml file&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_xml "&gt;    &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;destination&lt;/span&gt; &lt;span class="attribute"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;ActiveRecordService&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&amp;gt;&lt;/span&gt;
        &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;properties&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;source&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;ActiveRecordService&lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;source&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;properties&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;destination&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;A server restart is required when changing ActiveRecordService. When invoking create_fixtures this reloads the fixture based on the provided table names, however it overwrite the tables content of the database mode (development, test or production) for which you server is currently running in. I use the development mode during this exercise, so my weborb_development tables will be loaded with the fixtures.&lt;/p&gt;


&lt;h3&gt;3.b) Now let&amp;#8217;s invoke the create_fixtures from our flex unit test.&lt;/h3&gt;

Warning, I haven&amp;#8217;t found a nice way (yet) to transparently invoke the create_fixtures from the setup of the test. So for now each test method we will have three methods 1) that notifies that the test method is asynchronous and invokes the create_fixtures methods, 2) the callback of the create fixtures that will perform the &amp;#8216;real&amp;#8217; remote call we want to perform, and 3) the callback of the &amp;#8216;real&amp;#8217; remote call to perform the assertions. That&amp;#8217;s when you wish that Flex supports directly synchronous calls. However this can be wrapped way nicer than I just did. I will certainly refactor this once I need to write more tests.
&lt;p/&gt;

Edit the rails/test/fixtures/customers.yml as follows:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;first:
  id: 1
  name: Daniel
  address: Littleton
another:
  id: 2
  name: Samuel
  address: Bernex&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;The test now  looks as follows:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;package {
     import flash.events.Event;

     import flexunit.framework.TestCase;

     import mx.rpc.events.FaultEvent;
     import mx.rpc.events.ResultEvent;
     import mx.rpc.remoting.RemoteObject;
     import mx.rpc.AsyncToken;     
    import mx.collections.ItemResponder;
    import mx.controls.Alert;

     public class WebORBReadOnlyTest extends TestCase {

          public function WebORBReadOnlyTest( methodName:String = null ) {
               super( methodName );
        }

        // The mechanism to invoke the server side create_fixtures method is still a little clunky here.
        // This should be part of the setUp method, which doesn't support asynchronous setUp for now.
        // So writing a test with fixture now requires three method (that's the really clunky part!)
        //     1. the testXXXXX method that must call the getActiveRecordService and the create_fixture method.
        //     2. the method that will actual call the server (here. doGetCustomerList)
        //     3. the result handler for the abort call that will perform the assert.
          public function testGetCustomerList():void {
             // getActiveRecordService - Signal to TestCase that this is an asynchronous test
             // and pass end point of the test method (in this case the onCustomerListResult method)
             var activeRecordService:RemoteObject = getActiveRecordService(onCustomerListResult); 
              create_fixtures([&amp;quot;customers&amp;quot;], doGetCustomerList, activeRecordService);
           }          
           private function doGetCustomerList(activeRecordService:Object):void {
             activeRecordService.list(&amp;quot;Customer&amp;quot;);                       
           }
           // This is the even handler trigger by the asynchronous response, let assert that we received what we expected.
        private function onCustomerListResult(event:Event, token:Object=null):void 
        {
            assertTrue(event.toString(), event is ResultEvent); // First param is message.
            var data:Object = ResultEvent(event).result;
            assertEquals(2, data.length);
            assertEquals(&amp;quot;Daniel&amp;quot;, data[0].name);
            assertEquals(&amp;quot;Littleton&amp;quot;, data[0].address);
        }

        private function getActiveRecordService(resultHandler:Function, timeOut:Number=2000):RemoteObject 
        {
              var asyncCall:Function = addAsync(resultHandler, timeOut);
             var activeRecordService:RemoteObject = new RemoteObject();   
            activeRecordService.destination = &amp;quot;ActiveRecordService&amp;quot;;
            activeRecordService.addEventListener(&amp;quot;result&amp;quot;, asyncCall);
            activeRecordService.addEventListener(&amp;quot;fault&amp;quot;, asyncCall);
            return activeRecordService;            
        }

        private function create_fixtures(table_names:Array, callback:Function, callbackData:Object):void 
        {
             var activeRecordService:RemoteObject = new RemoteObject();   
            activeRecordService.destination = &amp;quot;ActiveRecordService&amp;quot;;
             var call:AsyncToken = activeRecordService.create_fixtures(table_names);    
            call.addResponder(new ItemResponder(onCreateFixturesResult, onCreateFixturesFault));
            call.callback = callback;
            call.callbackData = callbackData;
        }
        private function onCreateFixturesResult(event:ResultEvent, token:Object=null):void 
        {
            event.token.callback(event.token.callbackData);
        }
        private function onCreateFixturesFault(event:Event, token:Object=null):void
        {
            fail(&amp;quot;Failed to create fixtures. &amp;quot;+event.toString());
        }            

      }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;4. Implementing a deep find&lt;/h2&gt;

	&lt;p&gt;With the default WebORB&amp;#8217;s DataService implementation you cannot extract a Customer and his relationships (we will add them shortly) in one call. However this is where the &lt;span class="caps"&gt;AMF&lt;/span&gt; protocol really shines as nested structure can be serialized over http in one call. This is similar to what &lt;span class="caps"&gt;XML&lt;/span&gt; could provide but allows  strongly typed objects to be mapped between Flex and Ruby On Rails. The current Customer model  is not very representative for an application, so let&amp;#8217;s extend our model as follows:&lt;br/&gt;&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://onrails.org/files/extended_model.gif"/&gt;
&lt;p/&gt;&lt;/p&gt;


	&lt;p&gt;I know you may want to argue why is the ship_to/bill_to on the customer and not on the order. Hey, it&amp;#8217;s just for testing purpose for now, just to have some richer relationships between objects :-)&lt;/p&gt;


&lt;h3&gt;4.1 Extending the Model&lt;/h3&gt;
 the following command to generate the new models

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt; ./script/generate model Address 
 ./script/generate model Order --skip-migration  
 ./script/generate model  Item --skip-migration  &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
This creates the active records, the fixtures and the db/migrate/002_create_addresses.rb database migration file.
&lt;p/&gt;

Edit 002_create_addresses.rb as follows and run &amp;#8216;rake migrate&amp;#8217; 
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;CreateAddresses&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ActiveRecord&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Migration&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;self.up&lt;/span&gt;
    &lt;span class="ident"&gt;create_table&lt;/span&gt; &lt;span class="symbol"&gt;:addresses&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;t&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
      &lt;span class="ident"&gt;t&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;column&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;street&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:string&lt;/span&gt;
      &lt;span class="ident"&gt;t&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;column&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;zip&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:string&lt;/span&gt;
      &lt;span class="ident"&gt;t&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;column&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;city&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:string&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="ident"&gt;create_table&lt;/span&gt; &lt;span class="symbol"&gt;:orders&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;t&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
      &lt;span class="ident"&gt;t&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;column&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;customer_id&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:integer&lt;/span&gt;
      &lt;span class="ident"&gt;t&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;column&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;created_at&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:datetime&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="ident"&gt;create_table&lt;/span&gt; &lt;span class="symbol"&gt;:items&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;t&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
      &lt;span class="ident"&gt;t&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;column&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;order_id&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:integer&lt;/span&gt;
      &lt;span class="ident"&gt;t&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;column&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;quantity&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:integer&lt;/span&gt;
      &lt;span class="ident"&gt;t&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;column&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;product&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:string&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;        
    &lt;span class="ident"&gt;remove_column&lt;/span&gt; &lt;span class="symbol"&gt;:customers&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:address&lt;/span&gt;
    &lt;span class="ident"&gt;add_column&lt;/span&gt; &lt;span class="symbol"&gt;:customers&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;bill_to_address_id&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:integer&lt;/span&gt;
    &lt;span class="ident"&gt;add_column&lt;/span&gt; &lt;span class="symbol"&gt;:customers&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;ship_to_address_id&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:integer&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;self.down&lt;/span&gt;
    &lt;span class="ident"&gt;drop_table&lt;/span&gt; &lt;span class="symbol"&gt;:addresses&lt;/span&gt;
    &lt;span class="ident"&gt;drop_table&lt;/span&gt; &lt;span class="symbol"&gt;:orders&lt;/span&gt;
    &lt;span class="ident"&gt;drop_table&lt;/span&gt; &lt;span class="symbol"&gt;:items&lt;/span&gt;
    &lt;span class="ident"&gt;add_column&lt;/span&gt; &lt;span class="symbol"&gt;:customers&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:address&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:string&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

And define the ActiveRecord relationships as follows:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;class Customer &amp;lt; ActiveRecord::Base
  has_many :orders
  belongs_to :bill_to_address, :class_name =&amp;gt; &amp;quot;Address&amp;quot;, :foreign_key =&amp;gt; &amp;quot;bill_to_address_id&amp;quot;
  belongs_to :ship_to_address, :class_name =&amp;gt; &amp;quot;Address&amp;quot;, :foreign_key =&amp;gt; &amp;quot;ship_to_address_id&amp;quot;  
end
class Address &amp;lt; ActiveRecord::Base
  belongs_to :customer
end
class Order &amp;lt; ActiveRecord::Base
  belongs_to :customer
  has_many :items
end
class Item &amp;lt; ActiveRecord::Base
  belongs_to :order
end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

And the define some more fixtures:
&lt;div class="typocode"&gt;&lt;div class="codetitle"&gt;customers.yml&lt;/div&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;first:
  id: 1
  name: Daniel
another:
  id: 2
  name: Samuel&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="typocode"&gt;&lt;div class="codetitle"&gt;addresses.yml&lt;/div&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;first:
  id: 1
  street: First Street.
  zip: 80246
  city: Littleton  
another:
  id: 2
  street: Other Avenue.
  zip: 1200
  city: Bernex  &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="typocode"&gt;&lt;div class="codetitle"&gt;orders.yml&lt;/div&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;hardware_order:
  id: 1
  customer_id: 1
  bill_to_address_id: 1
book_order:
  id: 2
  customer_id: 1
  bill_to_address_id: 1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="typocode"&gt;&lt;div class="codetitle"&gt;items.yml&lt;/div&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;media_center:
  id: 1
  order_id: 1
  product: iTv
  quantity: 1
screen:
  id: 2
  order_id: 1
  product: 200&amp;quot; LCD Screen
  quantity: 1
remote:
  id: 3
  order_id: 1
  product: Remote Control
  quantity: 1
book1:
  id: 4
  order_id: 2
  product: Agile Web Development With Rails, 2nd Edition
  quantity: 1
book2:
  id: 5
  order_id: 2
  product: Mastering CSS
  quantity: 1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;4.2 Add get to ActiveRecordService&lt;/h3&gt;

The rails ActiveRecord.find method allows for the :include option to specify what relationship should be retrieved as part of the find. This will allow to perform 1 call and retrieve the customer, his address and all of his orders and order items.
&lt;p/&gt;

	&lt;p&gt;Let&amp;#8217;s extend ActiveRecordService as follows (we show only the new methods):&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;ActiveRecordService&lt;/span&gt; 

  &lt;span class="comment"&gt;# Allow for a deep fetch (find_by_id with :include options)    &lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;get&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;model_name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;options&lt;/span&gt;&lt;span class="punct"&gt;={})&lt;/span&gt;
    &lt;span class="ident"&gt;model_class&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Object&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;const_get&lt;/span&gt; &lt;span class="ident"&gt;model_name&lt;/span&gt;
    &lt;span class="ident"&gt;find_options&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt;&lt;span class="symbol"&gt;:include&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;options&lt;/span&gt;&lt;span class="punct"&gt;['&lt;/span&gt;&lt;span class="string"&gt;include&lt;/span&gt;&lt;span class="punct"&gt;']}&lt;/span&gt; &lt;span class="comment"&gt;# Here we limit options for now.&lt;/span&gt;
    &lt;span class="ident"&gt;result&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;model_class&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;send&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:find_by_id&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;find_options&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="ident"&gt;result&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;inspect&lt;/span&gt;
    &lt;span class="ident"&gt;result&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;  

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;find_all&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;model_name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;options&lt;/span&gt;&lt;span class="punct"&gt;={})&lt;/span&gt;
    &lt;span class="ident"&gt;model_class&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Object&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;const_get&lt;/span&gt; &lt;span class="ident"&gt;model_name&lt;/span&gt;
    &lt;span class="ident"&gt;find_options&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt;&lt;span class="symbol"&gt;:include&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;options&lt;/span&gt;&lt;span class="punct"&gt;['&lt;/span&gt;&lt;span class="string"&gt;include&lt;/span&gt;&lt;span class="punct"&gt;']}&lt;/span&gt; &lt;span class="comment"&gt;# Here we limit options for now.&lt;/span&gt;
    &lt;span class="ident"&gt;result&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;model_class&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;send&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:all&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;find_options&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="ident"&gt;result&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;inspect&lt;/span&gt;
    &lt;span class="ident"&gt;result&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;  
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;4.3 Call the new get method from our flex unit test&lt;/h3&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;          public function testGetFirstCustomer():void {
             var activeRecordService:RemoteObject = getActiveRecordService(onGetFirstCustomerResult); 
              create_fixtures([&amp;quot;customers&amp;quot;, &amp;quot;addresses&amp;quot;, &amp;quot;orders&amp;quot;, &amp;quot;items&amp;quot;], doGetCustomerFirstCustomer, activeRecordService);
           }          
           private function doGetCustomerFirstCustomer(activeRecordService:Object):void {
            var options:Object = {'include':['bill_to_address', {'orders':'items'}]};
             activeRecordService.get(&amp;quot;Customer&amp;quot;, 1, options);                       
           }
        private function onGetFirstCustomerResult(event:Event, token:Object=null):void 
        {
            assertTrue(event.toString(), event is ResultEvent); // First param is message.
            var customer:Object = ResultEvent(event).result;
            assertEquals(&amp;quot;Daniel&amp;quot;, customer.name);
            assertEquals(&amp;quot;Littleton&amp;quot;, customer.bill_to_address.city);
            assertEquals(2, customer.orders.length);    // 2 order
            assertEquals(3, customer.orders[0].items.length); // the first has 3 items
            assertEquals(&amp;quot;Remote Control&amp;quot;, customer.orders[0].items[2].product); 
        }  &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Now that is getting more interesting. From flex in the doGetCustomerFirstCustomer method the following call activeRecordService.get(&amp;#8220;Customer&amp;#8221;, 1, options); returns the customer his addresses, his orders and all order items. It would be even nicer if we could call Customer.find(1, options).&lt;/p&gt;</description>
      <pubDate>Sun, 29 Oct 2006 20:21:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:3dbee64c-0e24-4ba9-b4f6-9ea59f140328</guid>
      <author>Daniel Wanja</author>
      <link>http://onrails.org/articles/2006/10/29/part-1-using-weborb-to-access-activerecords-from-a-flex-application</link>
      <category>Ruby On Rails</category>
      <category>FlexUnit</category>
      <category>Flex</category>
      <category>ActiveRecord</category>
      <category>WebORB</category>
    </item>
  </channel>
</rss>
