Dissecting Rails, Part 1
Posted by tom March 13th, 2006
How does RAILS work and in specific how does it’s ORM (Object-Relational Mapping) work? A bit of it’s power is exposed in the below code, which is a normal Ruby program using the ActiveRecord orm-library.
require “rubygems”
require_gem “activerecord”
ActiveRecord::Base.establish_connection(
:adapter => “mysql”,
:host => “localhost”,
:username => “depot”,
:database => “depot_development”)
class Product < ActiveRecord::Base
end
product = Product.find(1)
product.price = “34.99”
product.save
As you can see hardly anything needs to be configured! ActiveRecord susses out that the Product class should be mapped to the products table. It does this by making the assumption that the table name is the plural of the class name, but all in lowercase.
It also checks the database for the columns the table has and maps these to the classes attributes.
This assumption is ActiveRecord’s default behaviour (using the pluralize_table_names attribute of the ActiveRecord::Base class), which you can override using theenvironment.rb in your config folder:
ActiveRecord::Base.pluralize_table_names = false
If you do not like this behaviour, or you need to deal with legacy tables, just specify the table name in the class definition as follows:
class Product < ActiveRecord::Base
set_table_name “prod”
end
This will make ActiveRecord look for the table “prod” instead of the table “products”.
So how does ActiveRecord find out about these columns? We’ll basically it does a query on the database (in my case MySQL): SHOW FIELDS FROM products; which returns all column names as follows:
+----------------+---------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------------+---------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | title | varchar(100) | NO | | | | | description | text | NO | | | | | image_url | varchar(200) | NO | | | | | price | decimal(10,2) | NO | | | | | date_available | datetime | NO | | | | +----------------+---------------+------+-----+---------+----------------+ 6 rows in set (0.01 sec)It maps these to attributes and stores them in this case in Product.columns.map and Product.columns_map. We’ll there’s probably more interesting stuff I’ll find out, but enough for now.

Leave a Reply