public
Description: Ruboss Framework Rails 2.+ Integration Support (Rails Plugin).
Homepage: http://ruboss.com/framework
Clone URL: git://github.com/dima/ruboss_rails_integration.git
name age message
file .gitignore Tue Aug 26 21:34:49 -0700 2008 Adding functional tests for ruboss rails integr... [Scott Patten]
file README Sat Jul 05 15:36:44 -0700 2008 1. Genamed generators to ruboss_* instead of r*... [dima]
file Rakefile Fri Jun 06 17:48:09 -0700 2008 refactored rails 2.+ support [dima]
directory config/ Fri Jun 06 17:48:09 -0700 2008 refactored rails 2.+ support [dima]
directory generators/ Fri Aug 15 12:03:53 -0700 2008 Cleaned up generated templates a bit. Removed c... [dima]
file gpl-3.0.txt Sat Jun 28 23:03:00 -0700 2008 switched to keeping both licenses in the code, ... [peterarmstrong]
file init.rb Sun Jun 29 00:20:19 -0700 2008 Updated license on remaining rails integration ... [dima]
file install.rb Sat Jul 05 15:36:44 -0700 2008 1. Genamed generators to ruboss_* instead of r*... [dima]
directory lib/ Wed Aug 27 17:08:08 -0700 2008 Merge branch 'master' of git://github.com/spatt... [dima]
file rcl-1.0.txt Sat Jun 28 23:03:00 -0700 2008 switched to keeping both licenses in the code, ... [peterarmstrong]
directory recipes/ Fri Jun 06 17:48:09 -0700 2008 refactored rails 2.+ support [dima]
directory script/ Tue Jul 22 22:40:25 -0700 2008 git rid of the clean argument. just removing st... [dima]
directory tasks/ Fri Aug 29 00:09:21 -0700 2008 fixing rake tasks for windows. [dima]
directory test/ Tue Aug 26 21:34:49 -0700 2008 Adding functional tests for ruboss rails integr... [Scott Patten]
file uninstall.rb Sat Jul 05 15:36:44 -0700 2008 1. Genamed generators to ruboss_* instead of r*... [dima]
README
Introduction
-------------
In this tutorial we will build a new Rails application from scratch using the Ruboss Framework. This is made pretty 
simple thanks to the generators that accompany the framework. However, the real beauty is in the actual generated code 
which uses the framework -- this is clean Flex code, and it is very similar to the code you would write.

Assumptions
-----------
The following steps have been tried with Flex Builder 3 on Mac OS X. You should have Git, Ruby on Rails *2.1* and MySQL 
5.0+ installed for the Ruby on Rails portion of this tutorial and Flex Builder 3 if you intend to edit your Flex code 
using it (NOTE: this is not required if you have Flex SDK installed: make sure you have added Flex SDK bin directory to 
your $PATH variable so that you can invoke mxmlc from the command line). This tutorial assumes that you are going to 
install the Ruboss Rails plugin directly from github (which is why Git is necessary). If you install the plugin in some 
other way then you don't need Git.

Developing a Flex application that talks to Ruby on Rails with Ruboss Framework
-----------------------------------------------------------------------------
This application will be called pomodo:

$>rails -d mysql pomodo

Next, we switch to the new application directory and install the ruboss plugin:

$>cd pomodo
$>./script/plugin install git://github.com/dima/ruboss_rails_integration.git

Next, we run the rconfig generator to create the new Flex project:

$>./script/generate ruboss_config

If you are using a non-default Rails configuration with a root password defined for your local MySQL database, you'll 
also need to run this next step. Otherwise you can safely ignore the following rake task and proceed to the next step.

$>rake db:mysql:stage ADMINPASS=<mysql root password> USER=<application username> PASS=<application password>

This rake task will modify config/database.yml (and save original database.yml definitions into database.yml.sample) to 
use the user/password combination you've defined above. It'll also grant appropriate permissions in the MySQL database 
and attempt to drop, then recreate appropriate rails application database defined by RAILS_ENV.

If you want to perform db:mysql:stage for all the databases defined in config/database.yml run the following command 
instead:

$>rake db:mysql:stage:all ADMINPASS=<mysql root password> USER=<application username> PASS=<application password>

Next, we proceed to scaffold our application.

Using YAML to scaffold your Flex+Rails application
--------------------------------------------------
Scaffolding is a cool way to get started with a Rails (and now Flex) applications quickly. Unfortunately, things tend to 
become quite cumbersome once you get beyond 5 or so models. You have to individually run scaffolding for each model and 
then go and edit relationships in both rails and flex code. This approach just doesn't scale. You might tolerate doing 
all this manual work for a few models, but what are you going to do when you have to run pretty much the same command 30 
or 40 times and then remember how all these things relate to each other? Wouldn't it be better if you could specify the 
bulk of your data model in some easy to read file and just run that once?

This is basically the intuition behind yamlscaffold script.

Let's create a file called db/model.yml that contains the following:
project:
 - name: string
 - notes: text
 - start_date: date
 - end_date: date
 - completed: boolean
 - belongs_to: [user]
 - has_many: [tasks]

location:
 - name: string
 - notes: text
 - belongs_to: [user]
 - has_many: [tasks]

task:
 - name: string
 - notes: text
 - start_time: datetime
 - end_time: datetime
 - completed: boolean
 - next_action: boolean
 - belongs_to: [project, location, user]

note:
 - content: text
 - belongs_to: [user]

user:
 - login: string
 - first_name: string
 - last_name: string
 - email: string
 - has_many: [tasks, projects, locations]
 - has_one: [note]

This should be fairly self explanatory except for a few details you might not have seen in YAML documents before.

  1. You can specify most of the aspects of the models (including relationships) directly in the YAML file:
    A. Use belongs_to: [<references here>] notation (e.g. belongs_to: [user]) to refer to the belongs_to end of the 
    relationship.
    B. has_one: following by an array of model names to denote has_one end of relationship (e.g. has_one: [note])
    C. has_many: works the same way has_one and belongs_to do.
  2. - in front of every attribute line preserves the exact order of elements in generated code. Make sure you add it!
  
That's pretty much all there is to it. If your db/model.yml file contains the text above, you can run:

$>./script/yamlscaffold

And watch scaffolding fly by on the console.

Check out the Flex and Rails code after you run the command. It should have all the fields and relationships set up. 
This means no more extra manual labour to get your application into a runnable state. Just load some data by running:

$>rake db:refresh

If you have added Flex SDK bin directory to your $PATH variable run:

$>rake ruboss:flex:build

This will compile your new Flex application and move generated .swf file into the public/bin directory.

If you *DON'T* have mxmlc executable accessible from the command line you'll have to open this project in Flex Builder 
and compile it.

Next, start the server by running:

$>./script/server

And point your browser at http://localhost:3000. It's not going to be the greatest Flex application ever written but for 
a 5 minute scaffolding job it's definitely not bad.

Porting Pomodo to AIR
---------------------

"ruboss_config" generator you've just seen above actually takes an optional argument, which is quite handy for 
converting our Flex project into an AIR project. Make sure you say "Y" when prompted to overwrite 
.actionScriptProperties, .project and Pomodo.mxml files:

$>./script/generate ruboss_config -a

It is recommended that you shutdown your Flex Builder before running the generator above (if you are running it). This 
generator will change a few Flex Builder specific files (such as .actionScriptProperties and .project) to include AIR 
specific information. This is how Flex Builder itself knows that it's dealing with an AIR project as opposed to a Flex 
one. It's not a very good idea to be changing Flex Builder specific files while it's running.

It's also a good idea to remove the Pomodo Run definition from Flex Builder (if you have it). To do that open "Run 
Dialog..." and delete Pomodo definition. Why is this a good idea? Well, we've previously run our application in Flex 
Builder as a Flex application. Flex Builder has saved that definition in its cache and is now convinced Pomodo is a Flex 
application. Converting this project to an AIR project makes the stuff Flex Builder has in its cache out of date. Our 
application is now going to be an AIR app. As far as Flex Builder is concerned these are not the same thing and they are 
run differently.

OK, let's open Flex Builder again. With Flex Builder pacified we can now get back to somewhat more intersting stuff. The 
generator command above will also convert your main application file to something like this:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
  xmlns:components="pomodo.components.*"
  layout="vertical"
  styleName="plain"
  initialize="init()">
  <mx:Script>
    <![CDATA[
      import org.ruboss.services.AIRServiceProvider;
      import pomodo.controllers.PomodoController;

      private function init():void {
        PomodoController.initialize([AIRServiceProvider], AIRServiceProvider.ID, "pomodo");
      }
    ]]>
  </mx:Script>
  <mx:TabNavigator width="100%" height="100%">
    <!-- For a simple demo, put all the components here. -->
    <components:ProjectBox/>
    <components:TaskBox/>
  </mx:TabNavigator>
</mx:WindowedApplication>

Basically the only thing the generator changed in the code is the way our main application controller is initialized 
during application start-up.

OK, you are all done, hit the run button and you should see the same application now running in AIR. It will have no 
data of course because there is no fixtures for AIR. So go ahead and create a few tasks and projects. They are now being 
saved to your local AIR database called "pomodo".

To recap: converting between a Flex application that talks to Rails server using XML-over-HTTP into an AIR application 
that's using local SQL database is just a matter of running one command. A command that only changes the way our 
application is initialized, NOT any of the code used to actually manipulate projects and tasks.

Getting Pomodo AIR application to talk to Ruby on Rails again!
------------------------------------------------------------
One nice thing about having much of the plumbing abstracted away is that you can now have your brand new AIR application 
talking to the Rails server again.

If you simply call "PomodoController.initialize()" with no arguments then XML-over-HTTP is going to be the default 
service provider. So let's change our Pomodo.mxml code to this:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
  xmlns:components="pomodo.components.*"
  layout="vertical"
  styleName="plain"
  initialize="init()">
  <mx:Script>
    <![CDATA[
      import org.ruboss.Ruboss;
      import pomodo.controllers.PomodoController;

      private function init():void {
        Ruboss.httpRootUrl = "http://localhost:3000/";
        PomodoController.initialize();
      }
    ]]>
  </mx:Script>
  <mx:TabNavigator width="100%" height="100%">
    <!-- For a simple demo, put all the components here. -->
    <components:ProjectBox/>
    <components:TaskBox/>
  </mx:TabNavigator>
</mx:WindowedApplication>

As you might have guessed this will tell the app to stop using local AIR database and start talking to the remote Rails 
server again. Remember to start your Rails server using "script/server" before running this app.

Finally, to convert our AIR application back into the Flex application it used to be run ruboss_config generator with no 
arguments again:

$>./script/generate ruboss_config

Again, remember to delete the Pomodo Run target and shutdown Flex Builder before you do that.

Copyright (c) 2008 Ruboss Technology Corporation, released under the GPLv3 license