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!

Planet Argon – Ruby on Rails Podcast

Planet Argonites Robby Russell and Jeremy Voorhis team up on Rails deployment, refactoring, databases, and National Album Recording Month.

Planet Argon – Ruby on Rails Podcast

Planet Argonites Robby Russell and Jeremy Voorhis team up on Rails deployment, refactoring, databases, and National Album Recording Month.

Update: time.onrails.org. Capistrano Rocks!

Updated time.onrails.org

The new functionality is

  • A first version of data export to text, csv, and xml. See the export icons in the bottom right of the projects and dashboard page.
  • A mini system message board. So we can leave you a message, i.e. for planned system maintenance downtime, or to announce new functionality.
  • The latest version of the Gruff Graphs

I realized that data export needs some more work as in Safari the xml doesn’t appear unless you do a view source and the csv doesn’t load Microsoft Excel directly nor adds a default .csv extension to the generated data.

We will deploy new functionality or fixes issues once a week if possible. Note that we are going to keep this application simple, but any suggestion is welcome. Contact us at time@onrails.org.

I deployed the application using Capistrano. It is pretty stressless and consists of the following steps:


rake remote:disable_web
rake remote:deploy_with_migrations
rake remote:enable_web

In this case we had a database migration, the new ‘messages’ table.

The only issue that persists is that the application doesn’t start right away after the deployment and seems to hang for about 10 minutes before comming back to life. The application is hosted on Dreamhost and we don’t have full control on how the displatch.fcgi processes are launched.

It’s now up and running, so enjoy!

render :update to |page|

In the following test I was checkeing out of the javascript that is generated using the render :update call. Note that using a functional test is also a nice way to explore some of the prototype_helper functionality.

page.call 'mycall', 'a', 2, 3    # -->  mycall("a", 2, 3);'
page.my_class.my_method 'a', 12    # -->  MyClass.myMethod("a", 12);

Now one issue I had was figuring out how to pass a javascript variable to a javascript call. I.e. mycall(p1, p2). The only way I found it so to use the page << method. After a little hacking I managed to pass javascript variables to a method using the page.call. See the use of the JsArugmentList class here after. Note it does get’s a little cluttered and the page << remains easier to read. Please let me know if you find a more elegant way to achieve this.

require File.dirname(FILE) + ‘/../test_helper’

  1. Little hack to allow passing javascript variables as argument to page.call
    class JsArgumentList
    def initialize(*arguments)
    @arguments = arguments
    end
    def to_json
    @arguments.join ’, ’
    end
    end

class RjsController < ActionController::Base
def rescue_action(e) raise e end;

  1. See prototype_helper.rb for implementation of the ‘page’ methods.
    def page_call
    render :update do |page|
    page.call ‘mycall’, ‘a’, 2, 3
    page.assign ‘p1’, ‘str1’
    page << ‘mycall(p1, p2);’
    page.call ‘mycall’, JsArgumentList.new(:p1,:p2) #equivalent to previous line
    page.my_class.my_method ‘a’, 12
    end
    end
    end

class RjsControllerTest < Test::Unit::TestCase
def setup
@controller = RjsController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end
def test_page_call
get :page_call
javascript = @response.body.split(“n”)
assert_equal ‘mycall(“a”, 2, 3);’, javascript0
assert_equal ‘p1 = “str1”;’, javascript1
assert_equal ‘mycall(p1, p2);’, javascript2
assert_equal ‘mycall(p1, p2);’, javascript3
assert_equal ‘MyClass.myMethod(“a”, 12);’, javascript4
end
end

Tim Bray – Ruby on Rails Podcast

Tim Bray, co-inventor of XML, talks about the appeal of Ruby as a dynamic language and where Java might have a place in the future of Rails. Also features Obie Fernandez and Dave Astels.

Tim Bray – Ruby on Rails Podcast

Tim Bray, co-inventor of XML, talks about the appeal of Ruby as a dynamic language and where Java might have a place in the future of Rails. Also features Obie Fernandez and Dave Astels.

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

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

CSS Transparent Rollovers

I was trying to implement some rollover effects when I stumbled over this article at mandarindesign. I wrapped this functionality in the helper here after


Project Dashboard Charts
<%= rollover_image(‘/images/index/project_icon.png’, true) %> <%= rollover_image(‘/images/index/dashboard_icon.png’) %> <%= rollover_image(‘/images/index/graph_icon.png’) %>



def rollover_image(src, over=false)
transON, transOFF = over ? [‘transOFF’, ‘transON’] : [‘transON’, ‘transOFF’]
content_tag “div”,
image_tag(src, :onmouseover => “this.className=‘#{transOFF}’”, :onmouseout => “this.className=‘#{transON}’” ),
:class => transON,
:onmouseover => “this.className=‘#{transOFF}’”,
:onmouseout => “this.className=‘#{transON}’”
end

Project Dashboard Charts
Project_icon
Dashboard_icon
Graph_icon