RailsConf 2006 - Here we come!

Looking forward meeting you all in Chicago! There will be tons of great presentations, here is my selection:

Friday
10:45 Introduction to Capistrano
Mike Clark is just a great presenter
13:15 ??
Not sure yet
14:30 Monitoring Rails Applications in Production Environments
Too important to skim that one
15:45 Sneaking Rails into the (legacy) system
or Goeffrey's Rails Deployment on Shared Hosts
Saturday
09:00 Ajax on Rails
Let's see what the 'man' has to say
10:15 Lessons from Blinksale and IconBuffet
I am eagerly waiting for some information on the Blinksale API
11:30 Lucene Eye for the Ruby Guy
We are using successfully Ferret, but Lee did all the programming, so it's time I do some catching up
14:45 Testing Migrations
I hesitate between this and the two other talks, but I got bit a couple of time with migrations. So any good advice is welcome.
Sunday
9:00 Beyond DHTML: Introducing Laszlo on Rails
I am big fan of Flex and Laszlo, now that Laszlo can generate DHTML, let's see what Mike has to say.
10:15 Just the Facts (and Dimensions) -- using Rails with your OLAP data model
I had the chance of beeing part of a team that pionered the field before it was called that (back in 1987). And now I need to do some more data analysis for the soon to be releases OSX RailsLogAnalyser application (Flex+Rails). Looking forward to this talk.
11:30 Rails Takes on the Enterprise with SOA
Rails is a tuff sell to the enterprise. They invested to much into Java and .Net, so even if Rails is often a good fit, it's not even considered. So any additional ammunition to enter existing enterprises is welcome

Posted by Daniel Wanja Tue, 20 Jun 2006 10:13:00 GMT


Geoip data

As part of the Rails Log Analyzer I want to show where, geographically speaking, the different users come from. The following 'ingredients' were required to achieve this:
  • The geoip gem by Clifford Heat
  • The GeoLiteCity.dat file download from http://www.maxmind.com/app/geolitecity
  • A vectorial world map in Flash from http://www.fabiovisentin.com/world_map/vectorial_world_map.asp
  • And the Flex mx:BubbleChart component
The result is the following

20060601_geoip.gif

Note there are still some technical hurdles to overcome with the bubble chart as it behaves unexpectedly when setting the radius of the bubbles and the scaling of the world map as the background of the chart can not be precisely controlled. Also the world map needs to be zoomed in a little to make the graph more readable as not too much activity is going on at the south pole.

So now lets look at some code extracts.

Getting the geoip information [ruby]

When parsing the log we retrieve the city information related to an ip address

  require 'geoip'

  geo_ip = GeoIP.new("#{RAILS_ROOT}/data/GeoLiteCity.dat")
      parser.items.each_with_index do |item, index|
     geo_info = geo_ip.city(item['ip']) 
             ...
  end
The _city_ method returns the following array
         	[   hostname,			# 0 - Requested hostname
         	    ip,				# 1- Ip address as dotted quad
         	    CountryCode[code],	# 2 - ISO3166-1 code
         	    CountryCode3[code],	# 3 - ISO3166-2 code
         	    CountryName[code],	# 4 - Country name, per IS03166
         	    CountryContinent[code],# 5 - Continent code.
         	    region,			# 6 - Region name
         	    city,				# 7 - City name
         	    postal_code,		# 8 - Postal code
         	    latitude,			# 9 - Latitude
         	    longitude,			# 10 - Longitude
         	] 

Generating the geo data series [ruby] The log file data is stored in sqlite database for ease of querying and aggregation. This will also allow to wrap the application as a packaged OSX application with the database embedded in the application. The following called is invoked by the controller that simply return the result of the query to the Flex application.

  def Hit.sqlite_data(from_date, to_date)
  result = {}
    query = { :name => "geoip",
                  :sql  => "select count(*) as count, latitude, longitude, city, state, country from hits where #{scope} group by 2,3 order by 1 desc",
                 :column_names => ['count', 'latitude', 'longitude', 'city', 'state', 'county']
               }

  result[query[:name]] = Hit.geoip_serie(data, query[:name],query[:column_names], result[:hit_count][:data][0][0].to_f)
  result
   end

  def Hit.geoip_serie(serie, title, column_names, total_count)
    result = {:title => title}
    data = []
    serie.each do |item|      
      row = {'count' => (item[0].to_f / total_count)*100,
             'latitude' => item[1],
             'longitude' => item[2],
             'city' => item[3],
             'state' => item[4],
             'country' => item[5],
             }
      row['count']  = 3 #if row['count'] < 1
      #row['count']  = 5 if row['count'] > 5
      data << row
    end
    result[:data] = data
    result
  end

Rendering the series [flex]

As seen in a previous article on how to exchange data between Flex and a Rails application using JSON, the server returns the data as a string that is simply transformed to an actionscript object using JSON.decode. This object is then passed to a custom component named BubbleSerieChart (I know, I find a more descriptive name)

Passing the series to a custom Flex component
<local:BubbleSerieChart time_serie="{geoip}" serie_name="GeoIP" />
The full source of the custom component.
<?xml version="1.0" encoding="utf-8"?> <mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml" title="{serie_name}" height="100%" width="100%"> <mx:Script> <![CDATA[ import mx.controls.Alert; [Bindable] public var time_serie:Object; [Bindable] public var serie_name:String; private function getLabel(item:Object, field:String, index:uint, percentValue:Number):String { return item.key; } ]]> </mx:Script> <mx:BubbleChart id="chart" dataProvider="{time_serie}" showDataTips="true" width="100%" height="100%" > <mx:backgroundElements> <mx:Array> <mx:Image source="@Embed('political_world_map_grey.swf')" /> </mx:Array> </mx:backgroundElements> <mx:horizontalAxis> <mx:LinearAxis minimum="-180" maximum="180" /> </mx:horizontalAxis> <mx:verticalAxis> <mx:LinearAxis minimum="-90" maximum="90"/> </mx:verticalAxis> <mx:series> <mx:Array> <mx:BubbleSeries xField="longitude" yField="latitude" radiusField="count" maxRadius="5"/> </mx:Array> </mx:series> </mx:BubbleChart> </mx:Panel>

Posted by Daniel Wanja Thu, 01 Jun 2006 12:20:00 GMT


An eCommerce platform in Ruby on Rails

I have the chance to be part of an amazing team since last October that created a new generation of eCommerce platform using Ruby on Rails that will power hundreds of high profile ecommerce websites. The first website powered by this platform is

www.nationaltabletennis.com

Gately’s, the company behind this development had the foresight one year ago to start the development from scratch of the three major applications forming the platform…using Ruby on Rails. This decision was driven by their technical director, Solomon White, who saw the potential of Rails that not many realized at that time and decided to form a top notch team. The three applications are order management, store builder, and the storefront engine. The storefront engine can drive multiple stores. You can get an idea of what such a store looks a like at www.nationaltabletennis.com. However most of the development went into the two back-end applications, that not only look amazing, but offers possibilities that will make news in the future.

Each of the three components of the platform consist of a large application by it-self. The storefront and the store builder are new applications and the order management replaces an older php applications. Together these applications have well over one hundred model classes. This is just to give an idea of the scale of the applications.

Now, the question is how well is Ruby On Rails adapted for larger scale development with a team of 5 developers and 1 designer?

Ruby On Rails kicks ass.

The many decisions that the Rails environment takes for you allows you to concentrate on what is important, like business logic, user interaction, quality. You spend very little time in the plumming of the application asking yourself where things should go or what artifacts should be used. Rails did these descisions for you. In addition, the different ways you have to exercise immediately a code change without any delay, by the console, through unit tests, or via a page refresh provides a dynamism to the development cycle that cannot be described in words but needs to be experienced. You can perform a quantity of changes in an hour that cannot be done in other environments like java. Not only code changes, but with the database migrations you can go back and forth between different data model structures, just to experiment. You start not just coding the first thing you decided on, but you start going in a “Oh, let’s try this” mode. Not all is shiny however. We had some difficulties sharing code between the three systems that had common model, views, and controllers. This was for the access rights. For some mysterious reasons I didn’t feel using the Plugins Engine that specifically addresses this problem. So I started to role-my-own, lighter version of a plugin engine, which works but is still causing some headaches from time to time. On the other hand, using the plugin architecture to share common code that doesn’t rely on views, is a simple and great solution. Furthermore to integrate the three applications we used secured, RESTfull http requests. This approach is so much simpler than webservices and with Rails you can modify the two applications that needs interaction in parallel, refining the interaction protocol, again seeing the results of any change immediately.

There is way more to describe, but as a former Java Enterprise developer and a former Microsoft Solution Developer, I can say that Ruby On Rails just kicks ass and leaves these other environments in the shadow.

If you are starting a new enterprise or web development project, you got to consider Ruby on Rails!

Posted by Daniel Wanja Thu, 27 Apr 2006 07:00:00 GMT


Graphs with Gruff (followup)

The solution from the source ;-) I checked it out and it now works as advertised, just add g.minimum_value = 0 to the Gruff::Bar before rendering it (g.to_blob).

Note that axis starting at zero.

Without the minimum_value With the minimum_value set to zero

Posted by Daniel Wanja Fri, 14 Apr 2006 06:49:00 GMT


LAUNCH time.onrails.org, time tracking made simple!

We call it time.onrails.org. It’s a new FREE online time tracking product for the consultant and programmer that bills by the hour or works on multiple projects.

We (Lee and I) have been using it for awhile now to track our Rails consulting work. It’s really the fastest way to count your hours across multiple projects. And we tried many of the solutions out there.

See time.onrails.org for an overview or go straight to signup and be up and running in 5 seconds.

Let us know what you think at time@onrails.org.

Enjoy!
Daniel

Posted by Daniel Wanja Thu, 13 Apr 2006 20:41:00 GMT


A source code browser

Browse::Source is a simple source code browsing application. It’s 100% based on Collaboa, it’s mostly the source code browser functionality but uses the file system rather than connecting to subversion.

I recently got a request from Justin to have access to some ‘old’ rails code (flexonrails) we wrote a while ago, and also Todd asked for the source code of autumnriders.
So I tried Collaboa but it requires to compile subversion from the source in order to have swig-rb. So I extracted the source code browser from Collaboa and removed the dependency on swig-rb. Now if all you need is to add simple source code browsing…then Browse::Source is what you need.

Well, we haven’t posted yet the two code bases mentionned above, but have a look at the source code browser source code Browse::Source

Posted by Daniel Wanja Mon, 20 Feb 2006 21:55:00 GMT


Graphs with Gruff

class GraphController < BaseTimeController
   def pages
      g = Gruff::Pie.new("500x350")
      g.title = "All Pages" 
      @current_user.pages.each do |page|
        g.data(page.title, [page.total]) 
      end
      send_data(g.to_blob, 
                :disposition => 'inline', 
                :type => 'image/png', 
                :filename => "timers.png")
    end
end

Pretty easy! Wasn’t it. Note the code above shows only the first of the graphs. Now if only I could find out how to set the minimum of the Bar chart to 0 instead of the minimum of the serie. Any help is appreciated?

Posted by Daniel Wanja Mon, 20 Feb 2006 12:10:00 GMT


I'd rather be on RAILS.

This statement is pretty true right now, Rails is just a pleasant development environment. Mike Clark left this sticker at my desk at one of the places I am currently doing a Rails project at.

For another client I am doing a Flex project and work with many great java developers. I thought I would put the sticker in a visible spot and see their reactions. Well, it didn’t fail, some of the comments where pretty funny. Here they go:

  • That’s a big statement.
  • We’ll run you out on a rail.
  • So you would rather be on rails, hein?
  • HuHan!
  • You really are a geek.
  • Where did you get it? You didn’t get one for me?
  • He’s a convert.
  • You are pushing the Ruby stuff today!
  • It looks like it should have a Lenin on it.
  • I’d rather be fishing.

The “Lenin” one I didn’t totally get, even after a long discussion, but I sounded pretty funny to me. As you see, give me a sticker and will say good things about you. No, that’s not the case, I just think Mike Clark and Dave Thomas are putting a very compelling training together, and with these two guys you will learn more in three days than you would ever in any other places. Check out http://pragmaticstudio.com and their new Rails Studio, coming to Denver in January.

Posted by Daniel Wanja Fri, 09 Dec 2005 21:44:00 GMT


An on-line store build with Ruby on Rails

In this non-technical article I wanted to share my impressions of writing an online store with Ruby on Rails. http://www.autumnriderstees.com/

Background

On September 9th Lee’s dad mentioned that he would receive a stock of new quality designer T-shirts with funny bikers logos on September the 22nd and asked Lee if he could setup an on-line store. Lee asked me if I could help out writing it in Ruby on Rails and if I thought it was feasible. Hey, I just finished “Agile Web Development with Rails”, how hard could it be, the book contains everything we need. So “heck, yea, we can do it”. So Lee told his dad: “Sure, we’ll do”. Well, it took us just a little longer, not much thought, considering we just met once a week for a month, and two weekends. But considering that Lee just started a new Rails gig, me just being father for the second time and a little sleep depraved, we manage to go-life on October the 16th at RubyConf 2005. First Ruby and Rails is really cool, Dave Thomas books are invaluable in many aspects, not the least being that the most of the order processing part of the application is taken straight from book.

Posted by Daniel Wanja Sat, 03 Dec 2005 15:04:00 GMT


RubyConf 2005 and RubyWeek

RubyConf 2005 and RubyWeek

What a Ruby Week. I am on the plane back to Denver from the Ruby Conference 2005 that just finished in San Diego. On the beginning of the week I started a new part-time job working on a Ruby on Rails application. On Thursday I flew to San Diego for the conference. Later that evening, with Lee we fleshed out the latest bug of our first on-line Rails application, and put it in production. If you are a Biker and like funny shirts, check out AutumnRidersTees.com. It’s a very small on-line shirt Store. Thank you Dave Thomas for your book on Rails, it was also a nice kick-start for our application, especially the non-public/administrative side of the site. On Friday the conference started, and what a conference, about two hundreds geeks and Ruby fans, inclusive many of the key players that create Ruby, Rails, and many of the awesome frameworks we are using everyday. It’s funny to put a face on who is behind these frameworks. For more info on the speakers checkout the agenda. Matz,the creator of Ruby, and ko1, the writer of the upcoming RubyVM, presented their views on the future of Ruby. I am not sure if this comes from the Japanese culture, but the elegance, simplicity and power, that radiates from the existing and forthcoming releases, made me want to to study this country. About 15 of the attendees came from Japan. It’s interesting how the community still feels small and is so open (and fun) when attending the conference especially when you realize the potential of Ruby and the power meta programming provides by creating domain specific languages. Rails is an example of that puts that power to good use. Speaking of Rails, David Heinemeier Hannsson, provided a nice state of the union for Rails and a hands-on workshop (he worked, we watched) of the forthcoming Rails 1.0 functionality. Rails was the trigger for me to dive into Ruby, and what is coming out will impress many java shops. SwitchTower to deploy applications from a single server to large clusters. Gauge to monitor your application and see what’s going on, live, on your servers. So many other improvements that are just practical. Tom took quite some notes of that presentation. Before the Rails talks I also enjoyed an interesting talk of domain specific languages in general by Jim Weirich followed by a Karlin Fox’s talk on how to create a user oriented specification and testing languages using “english” thus allowing a non-programmer user or business analyst to express the expected behavior of the application. The amazing part is that this domain specific language is implemented using Ruby and results in runnable unit test that excerse the user interface.

A great conference and a great Ruby week.

Posted by Daniel Wanja Sun, 16 Oct 2005 21:36:00 GMT