Some of the information here may be outdated, please check the book instead


This is a not a comparison of features. We really like Rails and we took some ideas from it.

The purpose of this document is to teach web2py to Rails programmer.

Rails is based on Ruby, web2py is based on Python

Create a Project

In Rails:

rails MyProject

In web2py -S MyProject

or, even better, use the web based administrative interface to create, deploy, manage, and edit projects.

The provided web2py admin works like for Rails but provides more functionality than heroku.

Hello World

In Rails

def world
    @greeting = "hello world!" 

In web2py

def world(): 
    return dict(greeting="hello world!")

In Rails variables to passed to the view start with @, in web2py they are explicitly returned in a dictionary.

Notice that in Rails you get a template missing error. In web2py you don't, you get a generic template render the message variable without complaints.


In Rails

  <% 16.times do |i| %>
     <%= @greeting %> <%= i %><br/>
  <% end %>

In web2py

  {{ for i in range(16): }} 
    {{= greeting }} {{= i }}<br/>
  {{ pass }}


In Rails

class AddTable < ActiveRecord::Migration
  def self.up
     create_table :user do |t|
     # id is created for us.
     t.column :name,    :string, :limit => 50, :null => false
  def self.down
    drop_table :user

In web2py


Notice that:

  • In rails you have to type various shell commands to perform the migration (create or drop the table) and you have to write additional code if you plan to alte the table.
  • In web2py is the table does not exist it is created, if it differs it is altered.
  • In Rails you specify the location of the DB in a config file.
  • In web2py you can connect to multiple DBs within the same app therefore you specify it in the model.

To select and delete a user in Rails


The same code in web2py is


On request, response, session

In web2py form variables are in request.vars and they can be accessed by

request.var.myvariable or request.vars['myvariable']

The first notation returns None if not request.vars.has_key('myvariable'). The second raises an exception. You can use request.post_vars to get only post vars and request.get_vars to get only get variables.

To store stuff in session you do


and you retrieve it with

  • Normally sesions are stored on disk and locked when in use.
  • It is also possible to store session on database.
  • sessions are saved automatically when web2py returns, unless specified otherwise.
  • It is possible for multiple apps to cooperate by sharing sessions and/or databases

The response object is used to stream data, create xmlrpc services and send some standard variables to the views


In Rails

redirect_to :action => 'list'

In web2py



Not native in Rails.

In web2py:

T('this is a message')

(and as usual no need to import anything since you are supposed to use T) You web2py you can also do

T('this is message %(name)s',dict(name='xxx'))
  • In both cases the expression is evaluated lazily when displayed in views.
  • In web2py, the web based administrative interface provides a translation page interface.
  • To create a language file in web2py just type its name (for example ) in the admin interface.


In Rails

<%= link_to "Create", :action => "new" %>

In web2py helpers have the same names as the corresponding HTML


produces the same output as

<a href="{{=URL(r=request,f='new')}}">Create</a>

Helpers can be nested as in

HTML(BODY(H1('title'),P('bla '*10,_id='main')))

and they can be used to build forms via FORM and INPUT.

Notice that web2py escapes all text displayed in views to prevent XSS. Only text marked by XML('...') is not escaped.


Rails comes with Scriptaculous. web2py comes with jQuery base. But with any of them you can use any JS library.


In Rails:

require 'json/objects'
def MyController < ApplicationController
    def give_me_json
       render :text => data.to_json

In web2py

import gluon.contrib.simplejson as sj
def give_me_json():
    return sj.dumps(dict(pages=pages))

What else?

  • web2py comes in one executable package including an SSL enabled web server, the sqlite database, a web administratve interface that allows you to create/edit/deploy and manage all your applications.

  • Exception are automatically caught by web2py which logs the traceback, the code causing the exception, and issues a ticket to the visitor that triggered the exception. No code is exposed to the visitor, not even by mistake, ever.

  • web2py includes libraries for generating CREATE/UPDATE/DELETE forms from your database tables.

  • web2py includes libraries for handling AJAX, JSON, REST, RSS, ATOM, RTF, CSV, WIKI (markdown) and some more protocols.

  • web2py has helpers that help you build objects that can be serialized in HTML or XML. Any correct HTML/XML can be generated using exclusively helpers.

  • web2py code runs on the Google App Engine.

  • web2py packages everything you need in one binary file that you don't even need to install. I keep mine on a USB stick. You just click on it and it start web server, the sqlite database, fires the browser for access to the administrative interface.

  • web2py deals with static files for you, streams them when they are large (both in upload and download), and automatically supports IF_MODIFIED_SINCE and PARTIAL CONTENT. You can do streaming audio and video without any extra tools or settings.

  • web2py can map URLs using regular expressions so that you can use it to handle legacy URLs.

  • web2py has no configuration files. You just create an empty app via the shell or the web based admin interface and create/edit your models, controllers and views (using an editor or the web based admin interface).

There is a repository of free web2py apps here and an interactive FAQ there.

© 2008-2010 by Massimo Di Pierro - All rights reserved - Powered by web2py - design derived from a theme by the earlybird
The content of this book is released under the Artistic License 2.0 - Modified content cannot be reproduced.