Two new eCommerce sites driven by Ruby on Rails. 5

Posted by Daniel Wanja Thu, 27 Jul 2006 10:06:00 GMT

While I was zipping a drink at the pool in Spain and visiting friends and family in Switzerland, the team at Gatelys.com was busy designing and configuring two new ecommerce stores using the Rails eCommerce platform I worked on while a Gatelys. And they have many more ecommerce sites to come.

www.sleekspaces.com and www.raysgolfshop.com

Rails is open for some serious business.

Note that most of the logos, graphics and layouts are done by Lomax which is the best graphic designer I know. Now if only I could find a way to hire him away :-)

This complements www.nationaltabletennis.com that was launched a couple of months ago:

Fowler on RubyGems

Posted by Lee Marlow Thu, 20 Jul 2006 21:05:00 GMT

Since Daniel came back from Europe, I figured I’d finally pick up his slack and write an entry. :)


Last night I went to the Boulder-Denver Ruby Group where Chad Fowler spoke about all things RubyGems. It was a laid back talk with a recap of gems past, present and future. Pre-RubyConf 2003 the ruby-talk list would get peppered with questions like “Where is Ruby’s CPAN?” At RubyConf 2003, when put on the spot by David A. Black about the topic, Matz basically said “if you build it, it will be included in ruby core. That led Jim Weirich, Rich Kilmer, Black, and Fowler to spend the next night coding what would become the RubyGems. They even demo-ed it at the conference. It has grown quite a bit since then and now could be called the de facto standard for library distribution in Ruby.

The latest version of RubyGems is 0.9.0, which has some not so minor scalability improvements. To get the latest version simple run gem update --system. Since RubyGems isn’t in core yet, you still need to require 'rubygems' or set your RUBYOPT environment variable to rubygems. There is another way when starting ruby you can pass it the -rubygems argument. “But you said it wasn’t in core... if it’s not in core, why does it have it’s own argument for the ruby interpreter?”“ It’s true, it’s not in core. This is actually just a little trick by Chad et al to make it look it is part of ruby. The -r argument tell ruby to require whatever parameter follows, so the gem crowd made an ubygems.rb file that only has one line of code in it …

require 'rubygems'
... and from that comes ruby -rubygems.

Bundled with gems is its own gem_server. Firing this up starts up a WebBrick server on port 8808 by default. Going to http://localhost:8808 will then display all of the gems you have installed and even link to the rdoc installed locally if it exists and to the docs on the web. It also can serve gems if you wish. This means other machines could point to your gem_server and install any of the gems that you have installed. You do this with the --source argument. Others could search what gems you have by running gem search -r --source http://your_machine:8808 search_string. There is even a tool index_gem_repository.rb that will create a directory that can be served by apache as a gem server, in case you want something a little beefier than webrick.

One interesting idea that Chad mentioned was making a meta-gem for your projects. All the gem would declare is its dependencies on the other gems that your project needs. That way when setting up a new machine you can just install your meta-gem from your gem_server and then it will automatically install all the necessary gems. Pretty cool.

Chad did a good job of describing how gems came to be and guiding us through some of the code with some nice anecdotes along the way.


P.S. The coolest part of the night was I’m going to be a volunteer at RubyConf `06! Chad was quick to warn me that there is no glamour involved. Oh well, I’m excited anyway.

Pickin' up the slack

Posted by Lee Marlow Wed, 28 Jun 2006 19:16:27 GMT

I guess I'll have to try to pick up the slack while Daniel's trekking around Europe. In case you don't know, I'm the guy named Lee that Daniel mentions from time to time. Hopefully, I'll be able to fill some space here with some useful tidbits about Rails, Ferret, and whatever else looks interesting. Have a great vacation, Daniel. We'll leave the light on for ya.

June - Rails Month

Posted by Daniel Wanja Wed, 28 Jun 2006 16:12:48 GMT

June was one of these 'Rails' month...With Lee we took on a new Rails project in the e-learning arena for some people with some really cool ideas. They wanted a html prototype at the end of the month, and overly optimistic as I am, I said why just a prototype, let's build the real thing. And we did. Now there is more to the application before it can go life than what we just build, but we managed to go from concept to a real working front-end in an extremely short time. Wired frame UI, intense object modeling discussions, html prototype, then build it with Rails. Rails just get's out of your way and let's you build a web application as fast as your brain allows :-) We where really surprised how fast a great application can be build. This was only part time, as my main project is working on gatelys.com new ecommerce platform. An astonishing Rails application. I also worked a little on RailsLogAnalyzer, a 'Rails production log' visualization application using Rails and Flex on OSX. But for that one I will wait that the Flash Player 9 is out for OSX Intel. Then RailsConf 2006. That was awesome, meeting 700 Rails enthusiasts, the Rails core team, and many Rails developers from the Denver area. I can just say: "Rails has a bright future!". But now is time for me to sit back, relax. I'll be on vacations for most of July. So see you then!

Streamlined - Will ROCK the Rails World 2

Posted by Daniel Wanja Sat, 24 Jun 2006 08:39:00 GMT

Streamlined is an open source framework for quickly creating data-centric applications with Ruby on Rails. Today Justin Gehtland announced during his 'Ajax on Rails' talk that Streamlined will be released at OSCON in July. I can best describe Streamlined as 'dynamic scaffolding' done right. Streamlined is a model driven way of generating data centric UI's. Justin demoed how to create and modify a data entry application. It provides search, crud functionality, support relationship between model, and way more. The framework adheres to the convention over configuration approach and provides a default behavior of the application than can easily be refined and enhanced. As opposed to scaffolding it doesn't generate code for the controller but provides a basic behavior. This will ROCK the software development world and accelerate many projects.

From the Streamlined website:
In the Abendsen release, Streamlined has been focused on solving the problems of our customers and our internal projects. Right now, Streamlined is focused on:

  • Generator for churning out the initial views and configuration
  • A declarative DSL for managing views, including relationship management, field selection, etc.
  • Full Ajax-enabled management views with sorting, paging and live search (with configurable field-inclusion)
  • A criteria query extension to Active Record
  • Context-sensitive help
  • An extensible component system for representing relationships at runtime
  • Export to xml/csv
  • REST-ful web service layer around all models
  • Atom support
  • Auto user-management and inclusion of declarative role-based authorization
  • Choice of layouts (Yahoo Grids or CSS Framework)
  • Theme support
  • Includes Javawin for in-browser windowing

This is the feature set we'll release at OSCON in July.

RailsConf 2006 - Here we come!

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

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

Derailed - Denver Ruby On Rails User Group. June 15th.

Posted by Daniel Wanja Thu, 15 Jun 2006 18:51:02 GMT

19:15 Doug Fales presentation: Rails by the Waypoints: Integrating a GPS Unit and a Digital Camera in the Era of the Mashup.

Doug will present this talk at RubyConf next week, so this is kind of a dry run for him in front of 25 people at the Derailed (Denver Ruby On Rails User Group) before the big event. About 5 other people from the attendance will also attend RailsConf. Cool, Denver is in force. Doug explained how he came to Rails and integrating it with GPS data, Flicker and Google maps...that's what happens when you got the crazy idea of running long distances in the middle of no where. Check out http://walkingboss.org/ in the next month as he will release a first public version of his application. In short, you can map your walking track recorded by a gps onto a google map and also upload and link your photos to the track based on the photos time-stamps. Doug now moves onto the "What I learned" writing this application. Site note: the funny thing is that besides Ara, everyone in the attendance uses a Mac. Ok, back to the presentation. Doug sees Ruby on Rails as the glue between the data and the client-side of the application. Another challenge was writing the GPS data mangling libraries. He describes how Ruby helped writing different blocks of functionalities (Search using the Ferret gem and acts_as_ferret, the data models, tagging, ...). He then describes the cost of development, where Rails offers you lots for free. Finally, he concludes with comments on how rails allows for creativity by solving lots of mundane problems for you and allowing for to keep your momentum.

20:15 Now onto to Ara Howard's presentation: Meta Programming

Ara is usually more involved with the Boulder Ruby User Group. He is a Ruby person first, then a Rails person. He got into Ruby about six years ago, and works in all manner of application domains and is specialized in data mangling (not directly his words). He defines Meta-programming as being code that writes code. That can be at compile time or a run time. You can have reflexive meta programming where a language can be used to generate output in the same language. Ruby is a very good meta-programming language and Rails makes heavy use of meta-programming. Rather than going paraphrasing Ara, I would certainly be incorrect as he is covering lot's of ground, check out his slides (this link is to his desktop, you can also find the slides at http://codeforpeople.com). Note that just the slides won't provide enough background as the narration Ara provides and the code examples augments greatly these slides. So try to catch one of his talks if you can. The nice part of his presentation is that he is presenting advanced aspects of Ruby, the languages, that may be more obscures to people like me that dived into Ruby via Rails. Ruby provides lots of hooks for meta programming like module_eval, class_eval, instance_eval, define_method, eval (being evil).

Two excellent presentations. Thank guys! Now onto Rock Bottom for a beer.

Geoip data

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

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>

Rails Log Analyzer - Rails and Flex with JSON 7

Posted by Daniel Wanja Mon, 15 May 2006 21:15:00 GMT

I started to write a small Rails Log Analyzer that provides some insight on how a given application is used. I’ve just spent three hours so far, so not too much to show, but I have found the integration of Flex with Rails for read-only purpose of the different time series pretty straight forward.

In two words…

RAILS: data.to_json

FLEX: JSON.decode(String(srv.lastResult));

On the Rails side

The controller simply transforms the Hash return by the model into a json textual representation.

the controller
class DataController < ApplicationController

  def overview
    render :text => Hit.overview_data.to_json
  end

end

This is an extract of the method that returns a Hash that contains the time series in an Array.

the model
def Hit.overview_data
    result = {}
    result[:header] = {:period => {:start => Hit.minimum(:time).to_s(:db), :end => Hit.maximum(:time).to_s(:db)}}
    result[:sessions_series] =
           {:by_day => Hit.data_serie(Hit.count(:session, :group => :day, :conditions => 'controller <> "HeartbeatController"'), "sessions by day")    }
    result
  end

On the Flex side

the view

   import com.macromedia.serialization.json.*;

   private function resultHandler(event:ResultEvent) : void
        {
            status = "Loaded. Parsing data...";
            var result:Object = JSON.decode(String(srv.lastResult));
            header = result.header;
            ts = getSerie(result.sessions_series.by_day.data);

  }

    <mx:HTTPService id="srv" url="http://10.37.129.2:3000/data/overview" result="resultHandler(event)" />

The service is invoked by the following actionscript call

        srv.send()

JSON doesn’t support Date objects out of the box, but it’s a nice way to exchange complex data such a Hash and Map between Rails and Flex.

Update: time.onrails.org. Add Notes to your time entries! 2

Posted by Daniel Wanja Mon, 08 May 2006 21:58:00 GMT

Updated time.onrails.org The new functionality is
  • Add notes to your time entries. You can now add notes from the Dashboard or your project pages.
  • Improved CSV export.
Some functionality I am considering next:
  • fixing the rendering in Internet Explorer. I just saw this bug since I installed Parallels on my MacBook pro.
  • Blinksale integration, I started to write the UI to submit a time section to generate an invoice via Blinksale, but I am still waiting to get access to the api. Unfortunatly I didn’t make to the beta of the API. I even tried to convince Josh Williams from Firewheel Design, to let me in on it, but without success. Thanks Josh for the quick response anyhow!

Older posts: 1 ... 15 16 17 18 19 20