If you're new here, you may want to subscribe to my RSS feed. So that you can read the latest updates about Web2.0 tools, Making Money Online, Tips in SEO, Ajax and many more. Thanks for visiting ProgramimiCOM!

Ruby on Rails handles data manipulation with the Active Record, which provides an Object Relational Mapping framework. If these sound a little like foreign words to you, keep reading; you’ll find that the way RoR handles ORM is a little different, and perhaps easier, than you might see it handled with other languages.Data and its manipulation is central to any application, whether it is a desktop or web-based application. Data can be represented and manipulated using different techniques.

One of them is the Object Relational Mapping technique or simply ORM. ORM maps the relational tables to the object-oriented classes. ORM frameworks provide the mapping and corresponding object/data manipulation services. In most of the server-side technologies, ORM frameworks constitute a totally different component stack. Hence it becomes the developer’s job to do the groundwork to create a connection between the ORM framework and other frameworks (such as web frameworks).

In the context of ORM frameworks, RoR is an exception. The ORM framework is built into the core of RoR in the form of Active Record. In this discussion, the focus will be on the basics of Active Record. The first section will focus on the basics of Active Record. The second section will detail the steps required in connecting the database, and in the third section I will use Active Record along with ActionController and ActionView in an example. So that’s the agenda.

Active Record: What is it?

Active Record is an ORM framework or layer distributed along with RoR. Even though the term distributed is used, the Active Record is built into the core of RoR. Since Active Record is an ORM layer, it provides the following mapping services:

1. Tables to Classes

2. Columns to Attributes

3. Primary Keys to Ids

4. Rows to Objects

The major difference between Active Record and other ORM frameworks/layers is the way mapping is done. Most of the popular ORM frameworks such as Hibernate use XML as the mapping container. However Active Record uses a convention-over-configuration methodology. Let me show you how it is done.

Tables to Classes

To map a table to a class, the class has to be derived from ActiveRecord::Base i.e. the Base class present within the ActiveRecord package. What essentially happens when a class is derived from ActiveRecord::Base is that the derived class acts as a wrapper for the database table. In understanding the table’s name, Active Record assumes that the pluralized name of the class is the name of the table. If the class name has multiple capital letters, it is assumed that the table name contains underscores between the words. Some of the examples are:

Table Name         Class Name

Orders                   Order

Line_Items          LineItem

Data                      Datum

This behavior can be turned off by the following two steps:

  • Set the global flag ActiveRecord::Base.pluralize_table_names to false. This flag is present in the environment.rb file in the config directory.
  • Override the default generation of a table name using the set_table_name directive.

For example, if a table named Orders is to be mapped to the class Order the code would be:

 class Order < ActiveRecord::Base

end

But if the class Order needs to be mapped to a table Order_QA then the code would be:

 class Order <ActiveRecord::Base

set_table_name “Order_QA” # Not “Orders”

end

Now let’s see how columns are mapped to attributes.

Columns to Attributes

Once a table has been mapped to a class, there is no requirement to explicitly map the columns to the attributes. That’s because Active Record determines the attributes of a table dynamically at runtime. Typically, Active Record reflects on the schema to configure the class that wraps the table. The following shows how the SQL data types are mapped to Ruby’s data types:

image001r.jpg

Next let’s look at how Primary key is mapped.

Primary Key to Ids

If you remember the example application from the first part of this

series, the table’s Primary key was named id and had the data type of integer. Though the logical one would have been the Order_id, yet this id was used. At first glance, this might be considered preposterous. However, if one looks at the long run, the id as the Primary Key has its benefits.

Let’s say that the Order_Id is based on a 16 digit format including the Item id, user id, and so forth. In the future if the Order_Id has to be increased to 20 digits by including the last 4 digits of an RFID based code, all the dependent table’s columns would have to be changed. That’s a large order for even a medium-sized application. The mapping is done dynamically. However, if the requirement is to map an existing Primary Key then it can be done as follows:

 class Order <ActiveRecord::Base

set_primary_key “orderId”

end

Rows to Objects

Whenever a retrieve operation is performed on a class, the corresponding SQL query is fired at the database and the row is retrieved, which is then used to populate the object of the same class. The values of the column in the retrieved row become the values of attributes of the object. In a nutshell, the row is mapped into the object. For example, the following returns an Order object having the id of 27:

an_order = Order.find(27)

That covers mapping. Now let’s see the steps involved in performing CRUD operations using Active Records.

Active Record: Steps to using it

Active Record minimizes the configuration requirements, yet demands that certain conventions be followed. These conventions form part of the steps of working with Active Record. Following are the steps:

1. Creating the table(s)

2. Connecting to the database

3. Creating the ORM

4. Applying CRUD operation

Of these first step is purely convention based. The table has to follow the convention or else one would have to override the default values. Here are the details:

Creating the table(s)

Since convention takes precedence over configuration in RoR, the table has to be created following certain conventions unless you want to override the convention. They are:

  • The name of the table should be in its plural form.
  • The Primary Key should be name id with the data type as integer.
  • If the table references another table, then the Foreign Key should be of the form <referenced table name in singular>_id.

So applying the first two conventions an order tables, SQL script for MySQL would look like:



 create table orders (

id int not null auto_increment,

name varchar(100) not null,

/* … */

primary key (id)

);

Connecting to the database

Just like everything else with RoR, a database connection is also abstracted out. That means an Active Record application makes generic calls, delegating the details to a set of database-specific adapters. To connect to a database, the establish_connection() method of Base class of ActiveRecord has to be called with connection parameters. These parameters differ for different databases. For example the following call creates a connection to a MySQL database called testrails on the server localhost using the given user name and password:



 order = Order.find(123)

order.name = “raj” order.save 

Delete

Active Record provides the delete method for deleting data. It supports both single row deletion as well as multiple row deletion. The following deletes the record having an id of 20:

 Order.delete(123)

And the following deletes the records with ids supplied as a list:



 Order.delete([2,3,4,5])

That completes the bird’s eye view of how to apply CRUD to an ORM using Active Record. The advanced services provided by Active Record for CRUD will be discussed in the future. In the next section I will be using the services of Active Record along with ActionController and ActionView to create a login module.

Rails in the Real World

Without much ado let’s get to work and see how to implement a login module. The requirements of the module are as below:

  • A form that allows the users to enter their user name and password.
  • A simple userid password verification implemented to check the credentials of the user.
  • Once they are logged in, we need to record the fact somehow for the rest of their session (or until they log out).

On the basis of the requirements, the following are the components required:

  • User.rb – Model for the user table.
  • login_controller.rb – The controller orchestrating the flow.
  • login.rhtml – View providing form for logging in.

Here is the user table:



 create table users (

id int not null auto_increment,

name varchar(100) not null,

password char(40) null,

primary key (id);

Next comes the model class. Since we are using the Active Record in RoR, there is no need to use the establish_connection method. Instead I will be using the database.yml file with the following information (since I am expanding upon the demo application created in the first part):



 development: adapter: mysql

database: demo_development

username:raj

       password:

       host: localhost

The command to generate the model class is:

ruby script/generate model User

The model class contains two methods- try_to_login which in turn calls login. Here is the code:



 class User < ActiveRecord::Base

def self.login(name, password)

find(:first, :conditions => 
[“name = ? and hashed_password =    ?”, name,password])

end

def try_to_login

User.login(self.name, self.password)

end

end

The login method contains the find method with criteria. The details of this will be covered in the next part. The logic is simple – the try_to_login method gets called by the controller. This method in turn passes the data to the login method. The requirement of layering is to provide implementation abstraction. The login method tries to retrieve the data corresponding to username and password (before anyone complains about lack of security please bear with me as this is not a full-fledged implementation).

Next comes the controller. For that here is command:

ruby script/generate controller Login

And here is the code that implements the login validation and session establishment.



 class LoginController < ApplicationController

def login

@user = User.new(params[:user])

logged_in_user = @user.try_to_login

if logged_in_user

session[:user_id] = logged_in_user.id 
#creating the session

#and putting user’s id in   #it

redirect_to(:action => “index”)

else

flash[:notice] = 


“Invalid user/password combination” end

end

end

And here is the view :

<% @page_title = “Add a User” -%>

<%= error_messages_for ‘user’ %>

<%= form_tag %>

<table>

<tr>

<td>User name:</td>

<td><%= text_field(“user”, “name”) %></td>

</tr>

<tr>

<td>Password:</td>

<td><%= password_field(“user”, “password”) %></td>

</tr>

<tr>

<td></td>

<td><input type=“submit” value=” ADD USER ” /></td>

</tr>

</table>

<%= end_form_tag %>

That completes the login application. If you compare it with similar applications in any other language, the result would tell you that the number of lines is really less in RoR-based code. In this discussion there are certain aspects of Active Record that I have left out. The left out pieces of the puzzle called Active Record will be covered in the next part. Till then…

by A.P.Rajshekhar