Professional on the Web is a portfolio directory for web agencies and freelancers. Its target market is by definition a narrow one. We wanted to attract as many web professionals as we could by giving them the opportunity to promote their work in the fastest and simplest way possible. We achieved this by developing a no-frills, easy-to-use web application.

Today everyone is registered to some sort of a community or web-based network and the majority of them require a lengthy and boring registration process. We decided to differentiate ourselves by building a simple and fast profile creation process. It takes less than a minute to go through the motions. Users enter a few basic personal details, their projects’ names and relative web addresses. Once the data has been inputed, thumbnail screenshots for each project are automatically generated and displayed on the their user home page.

When logged into the system, the professional’s public home page doubles as their editable settings page. They can edit their profile and projects, associate tags, and instantly preview all the changes on the same page. In-place editing and drag&drop functions make it a breeze and instantly gratifying to modify your home page.

Professionals can determine how they’re listed in the system’s directory by associating tags to themselves. Users are allowed to choose up to ten tags, which are automatically suggested from a pre-determined library, to indicate the kind of services and expertise they offer. Having only a limited number of tags to choose from insures that users select only the most relevant ones. And it reduces the risk that a couple of bad apples end up spamming the system and appearing on every list.

Funneling Down User Data

A month after the launch of Professional on the Web we analyzed users’ behaviors and produced a funnel diagram. It revealed how many visitors had viewed the sign up page, how many actually signed up and completed their profile, and how many had subsequently updated their projects portfolio.

After analyzing the results we revisited different areas of the interface to improve usability and increase the ratio between active users and total visitors. In particular:

  • We added a new footer area and populated it with all the secondary links that were cluttering up the sidebar. We relegated the RSS links, social bookmarking links, advertising links and banners, and the request for donations to the new footer. Freeing up room in the sidebar provided more focus on the system’s internal services and navigation.
  • With more room in the sidebar now available we added a new system feature: a third party Job Notice Board with the aim to build our own in the future.
  • We created a new area on the home page, below the top rated professionals, and gave room to three random professionals. The idea was that they’d also receive visits, take stock of the referrals to their websites and inspire them to return to Professional on the Web to update their portfolio.

In the future, we will also be redesigning the homepage. At the moment its main focus is on getting professionals to sign up. Once we have a healthy number of active users registered on the system we will downgrade the prominence of the Signup teaser and highlight other features and services.

Developing with Ruby on Rails

We chose Ruby on Rails as the system’s framework as we knew it would bring several benefits throughout the development phase.

When we started planning Professional on the Web we were very busy with client work. So we decided to avoid the bells and whistles and start developing only the essential functions to get the system online as soon as possible. In this respect Rails was phenomenal. Once we settled on the overall design we jumped in. Framework development, user testing and subsequent modifications were all carried out hand-in-hand. It took two of us just 20 days to complete the application.

The Pros of Rails

The MVC (Model View Controller) architecture lets you easily design, modify and improve the application. It is an architectural pattern that mainly decouples the database interface (Model) from the user interface (View). An intermediary component, the Controller, is placed between how the data is represented and how the end user interacts with it. Thanks to this split, each part of the application has one authoritative and unambiguous place and you can respect the DRY (Don’t Repeat Yourself) principle. For example, the database extracting function would reside inside the template linked to the table that the template refers to, while the user’s request would be handled by the relative controller.

This approach can make learning Rails a lengthier process. Indeed, when you first start coding with it, development is not as swift as it could be with PHP or ASP. But at a certain point (it took us six months) it all starts falling into place and you marvel at how easy it really is. You soon notice how things that seemed so hard in the beginning actually turned out to be very simple.

We used database versioning and Capistrano to help streamline and simplify deployments. They greatly reduce all the usual errors encountered during deployment and it especially makes life easier once the application starts growing and you need to scale all procedures. For example, if you need to make changes simultaneously to the database and the application’s code, Capistrano will create a new folder to copy the whole application to, make the requested database changes and then switch the current symbolic link to the new directory. This allows you to easily rollback if something goes wrong by switching the symbolic link back to the old directory. And the whole procedure takes only a few moments. There’s no need to waste time FTPing, manually creating new folders or symbolic links, or restarting dispatches.

Another advantage with Rails is that tests are automatically generated while developing the application. The test suites created for both the application model and the user interaction allow you to add new functions without adversely affecting existing ones. There are many useful test plugin libraries that we have found indispensable for our projects, such as:

  • Selenium on Rails lets you test client-side behaviors. Tests are easily created by recording a macro with Firefox. Then you can carry out the same tests on all other browsers (amongst which Internet Explorer, Opera and Safari) and on different operating systems (Windows, Mac and Linux). This allows you to pinpoint any browser specific issues, especially when implementing AJAX.
  • SpiderTest is an integration-testing script that crawls all pages of your application. It automatically checks if your HTML is valid and if links point to exisiting pages. It also follows all AJAX calls and fills out required fields to submit and test forms.

Ruby on Rails is also useful for its fragmented caching function which allows you to save HTML code fragments to disk. As a result Ruby doesn’t need to calculate all the respective views and database requests every time they’re required. This is particularly time-saving when dealing with objects that belong to many lists. “Partials” — fragments of Ruby HTML (RHTML) that can be included in a view — can then be easily cached and reused in other lists. Below you can see how we used fragmented caching for the different professionals’ list views:

<% cache("professionals/p_#{}") do %>
    # partial code
<% end %>

The beauty of this function is that you can introduce it retrospectively. All you need is to add the first and last lines of code inside the fragment. If you make changes to the fragment’s content, you will need to annul its disk cache. But even this is a simple operation with Rails. For Professional on the Web, we added an action in the User model for all modification requests made by a professional when editing their profile page:

after_save :destroy_cache

after_save is a Ruby callback which allows you to callback automatically the method destroy_cache following any change on a professional’s profile page. The code for destroy_cache is:

def destroy_cache
  fragment = "#{RAILS_ROOT}/tmp/cache/professionals/p_#{}.cache"
  File.delete(fragment) if File.exists?(fragment)

An added bonus with this approach was that it helped increase the application’s speed. Because the fragment was performing a complex calculation, it helped save similarly complex operations that other helpers and database requests would have had to execute. It also allowed us to cache the professional independently whenever they appeared on a list, such as under the CSS or HTML tag lists.

Plugins can also speed up development time. For instance, the registration process is added by using the acts_as_authenticated plugin, which allows you to compile the database, HTML pages and sent emails in under a minute. The same results could be obtained with a CMS, but Ruby’s main strength lies in its flexibility. You can create new plugins whenever needed and more efficiently than with any other framework.

The Cons of Rails

All said, we have to admit that Ruby on Rails has its drawbacks. Since Ruby’s functions are so readily adaptable, it is equally easy to abuse them. This is especially true of helpers as well as database connections. If, for example, you wanted to create a link you could write and call the function item_url(item), such as:

link_to "Show Item", item_url(item)

where item represents a professional and item_url would be something like:

url_for(:controller => 'site', :action => 'show', :id =>

This would generate HTML code as:

<a href="/site/show/1">Show Link</a>

However, it would be overkill when all you’d need to code is:

<a href="/site/show/<%= %>">Show Link</a>

This is a much more efficient way of generating the desired link rather than first calling the item_link function, which would then call the link_to function, which in turn would call the item_url function.

“Helpers” — small functions that can be used anywhere in a Rails app — like the above link helper are useful if the function is required in multiple views. Whenever you have to change the way that a link is associated to an object, you only have to alter it once in the helper’s code, instead of changing it everywhere it’s been used. But if the link generating function were placed in a list inside a view and were invoked tens or, worse, hundreds of times the app would noticeably slow. In this instance, using the direct version of the view would drastically improve the application’s performance.

A similar problem can arise with the ActiveRecord, an object-relational mapping (ORM) pattern. Since it is so easy to implement it can equally be abused. This could then develop into a much larger problem as soon as the application increases in complexity and the relationships between models proliferate. For instance, let’s assume that there’s a user (model User) with many associated tags (model Tag). If you wanted to list the tags associated to the user you could execute the following code:


The application would then execute two separate queries. So to remedy the problem you would then add:

User.find(:first, :include => :tags)

This allows you to execute a single query using the SQL JOIN query. Unfortunately, we noticed that you can slow the system down if you overuse this function, due to what is commonly known as “eager loading”. Indeed if you concatenate more objects to the equation it can result in very large data transfers, reducing the application’s performance. This is because you can’t specify individual fields in the request, so you’re obliged to receive all the table contents in the JOIN query.

Another drawback with Rails is that for even just a small application you need at least 40MB of dedicated memory. Amongst all the advantages with Rails, you do need to consider whether it is appropriate to develop with it if you’re only going to be creating a simple website. Otherwise you will risk using up 1GB of RAM with little more than 10 projects.


As a final remark, we must commend Ruby on Rails on the clean and self-explanatory code that you can write with it. This is especially important for the way we work. It means that we can each write separate code snippets and then assemble them without having to explain to one another what goes where and why one thing was written in a certain way. Overall, Rails has boosted our productivity and work flow and made Professional on the Web a better app.