Building Flex on Rails

I’ve been working on a Flex based component for a Ruby on Rails application I’m doing. So far, I’ve made few decent strides toward integration with the rails framework. The following describes my first pass at integration and build automation.

The first step was determining how I want to setup my file structure within my Rails project. Here’s what I came up with:
New directories/files are in bold. Project specific content, in italic.

	- app
	- components
	- config
	- db
	- doc
	+ flex
		+ components
			- build
			- $component_name$component_name.mxml
		- $application_name
	+ lib
		+ tasks
			• flex.rake
	+ log
		• flex.log
	+ public
		- flash
	- script
	- test
	- tmp
	- vendor

Now comes the fun part. Here is the contents of my flex.rake file:

    1 namespace :flex do
    2   #Find components and build them out
    3   components = []
    4   Dir.foreach('flex/components') do |filename|
    5     if filename.match /\.mxml$/
    6       component_name = filename.sub(/\.mxml$/, '')
    7       component_files = [File.join('flex/components', filename)].concat(Dir[File.join('flex/components', component_name,'**')])
    8       components << file("flex/components/build/#{component_name}.swc" => component_files) do
    9         puts `#{File.join(ENV['FLEX_SDK'], 'compc')} -source-path ./flex -output flex/components/build/#{component_name}.swc -include-classes components.#{component_name}`
   10       end
   11     end
   12   end
   13
   14   task :components => components
   15
   16   #Find applications and build them into the public/flash directory
   17   app_tasks = []
   18   Dir.foreach('flex') do |dirname|
   19     if !['components'].include?(dirname) && !dirname.match(/^\./)
   20       app_files = Dir[File.join('flex', dirname,'**.mxml')].concat Dir[File.join('flex', dirname,'**.as')]
   21       app_tasks << file( "public/flash/#{dirname}.swf" => app_files.concat(components)) do
   22         puts `#{File.join(ENV['FLEX_SDK'], 'mxmlc')} -library-path+=flex/components/build -output public/flash/#{dirname}.swf flex/#{dirname}/Application.mxml`
   23       end
   24     end
   25   end
   26
   27   task :build_all => app_tasks
   28
   29 end

So what’s happening here? First, (line 1) I create a rake namespace. This way I can name my commands whatever I want without polluting the global namespace. To invoke a task defined here, you use the namespace, a colon, then the task name. Example: rake flex:build_all.

The following section (lines 3-14) finds all components and builds them as .swc files into the flex/components/build directory. The output filename will be the same as the source file’s name. So, flex/components/Widget.mxml will become flex/components/build/Widget.swc. Note that this code is still rather primitive. It doesn’t currently check to see if the build was successful or not before moving on.

The last section (lines 17-27) finds all the applications and builds them into the public/flash directory. So, flex/gallery/Application.mxml will become public/flash/gallery.swf. It automatically makes all components defined above available and will rebuild the app if the components have changed. There are some drawbacks to this approach, such as the fact that all applications will be rebuilt if any components have been modified as the script doesn’t know which components go with which applications. This is a non-issue for me as I only have a single Flex app in my project.

I’m trying to keep with the theme of convention over configuration at this point. By placing your files in the correct locations, rake will automagicaly find and build all the parts of your flex app. The next task I’ve set out for myself is creating rails helpers to easily include our newly created bundles of Flex joy.

2 Responses to “Building Flex on Rails”

  1. clay says:

    i get it! lol j/k

  2. I should mention that this requires an environmental variable be setup. $FLEX_SDK should point to the bin directory of your copy of the flex sdk.

Leave a Reply