Enterprise applications are considered to be complex to design and develop. Technologies such as J2EE and .Net augment this generalization. But there are technologies and frameworks that beg to differ. Ruby is one of those technologies/languages and Ruby-on-Rails (also called RoR) is such a framework.Ruby-on-Rails differs from other technologies in the aspect that, while other enterprise technologies give more stress on configuration, RoR stresses convention, thus eliminating the need for lengthy configuration files based on XML. The base of RoR being Ruby gives it one more advantage, the advantage of working with a Very High Level Language. Above all RoR natively supports Model-View-Controller architecture.

However the question still remains: how effective and productive is RoR? In the world of web development where every new framework (whether based on Java or any other language) is touted to be the one to revolutionize the web programming paradigm, how can one be sure of authenticity of the claim? In this discussion I will try to present both the sides of RoR and leave the rest to your discretion.

The upcoming section will focus on the recurring terminology in the world of RoR. In the next section I will detail the steps to be followed in creating a database driven application in Ruby-on-Rails. In the last section, a real world data driven application will be created. That’s the outline for this discussion. Here I am making one assumption, that the reader is already familiar with Ruby’s syntaxes and semantics. With this in mind, let’s start the discussion.

Understanding the Terminology of Ruby-on-Rails

RoR is based on Ruby and it follows the MVC pattern. Now what is this MVC pattern and what are its types? MVC is short for Model View Controller where the components (obviously) are Model, View, and Controller. MVC comes in two flavors, MVC-Model I and MVC-Model II. Before going into the types of MVC and the type followed by RoR, let’s look at each of the components of MVC individually.

Model

The definition states that Model is “The domain specific representation of information on which the application operates.” Essentially, the Model is responsible for maintaining the state of the application. And state refers to the data contained within the instance of an application at a given instance.

In short, Model deals with the data of the application. However, in the absence of the context of usage, data is raw and useless. So Model contains the logic that transforms the data by enforcing the business rules that apply to the data. For example, if the application deals with customer orders, the Model would contain (obviously) the data related to the orders. Along with that, the Model would also contain the logics that govern the discounts and so forth.

View

The main function of the View component is to render the Model into a suitable form for user interaction, generally a GUI element such as textbox, combo box, and so on. To elaborate, the data within the Model has to be represented in a form that humans can read. This representation of data into a human readable form is done by View.

View uses various GUI controls to present the data to the user. Many times, the Model contains sets of data, out of which only the relevant ones have to be shown to the user. To achieve this, the View includes logic to retrieve the required data from a collection of data present in the Model. The logic present in the View is also known as Presentation Logic. If I use the previous example, if the Model contains data about different orders from the same customer and if all of the data from the orders must be displayed a single order at a time, then that logic would be in the View.

Controller

According to its definition, the Controller “Responds to an event, typically a user action and invokes changes on the model and perhaps the view.” That means controllers receive an event from the user (input), interact with the Model by either retrieving new data based on user input or updating the Model based on the data from the input, and display the appropriate view to the user. In a nutshell, the Controller defines the flow of application logic and thus orchestrates the application. Relying on the earlier example, when a customer updates an order, it is the controller that, in reality, updates the Model and shows the view according to the updated data.

Pictorially, the interaction between the Model, View and Controller would be:

mvc.jpg

On the basis of how the Controller is implemented, there are two types or models (not to be confused with the Model of MVC; here model means type) of MVC architecture.

The MVC-Model I is also known as the Page Centric MVC. In this type of MVC model, the Controller is embedded along with the View (or Page). The Model is separate. That means if a templating technology (like RHTML, JSP) is used, the logic of the Controller would be embedded with the template created using the templating technology.

In MVC-Model II, the Controller is separated from the View. If the components of MVC are taken as layers, then, in model II, all the layers are separate. The logic for the Controller is no longer embedded within a template (such as RHTML. JSP).

RoR follows MVC-Model II, which implies that the View and Controller are placed separately. View is placed in RHTML and Controller logic is embedded in ruby files. Hence Ruby-on-Rails based applications have to follow the MVC-Model II pattern. The steps required to create such an application are the focus of the next section.

A Ruby-on-Rails Application, Step by Step

Since any RoR application has to follow the MVC-Model II, the steps we must take involve the implementation of the three components of MVC. Yet the way the implementation goes, the components need not to be implemented from scratch as RoR has two points as guiding philosophies: DRY, or Don’t Repeat Yourself; and CoC, or Convention over Configuration.

The first point means that most of the code that gets repeated has been abstracted out into the framework. The second point means that all the management of the application is done by the framework on the basis of Conventions. The following are the steps essential for any kind of application to be developed:

1. Creation of Application structure.

2. Creation of the Controller.

3. Implementing the View.

4. Configuring the database.

5. Starting the server.

Of these, the fourth step comes into the picture only when the application requires database access. Each of these steps consists of one or more commands to create the corresponding components. So here is what’s to be done at each step:

Creation of the Application Structure

The first step in implementing any application is defining the directory structure in such a way that it reflects the components and the helping classes’ position within the application. For other frameworks, this has to be done by hand and linked with the framework by using the configuration files. In RoR, everything is done with a single command — rails — which takes the name of the application to be created as a parameter. There are configuration switches for the rails command but that will be discussed in the future. Coming back to creating the application structure, if the an application named demo has to be created, then change the directory where the structure has to be created and give the following command at the command line:

rails demo

and RoR will respond by printing out the directory structure created like this:

rails_demo.jpg

If a dir (or ls based on the OS) is give inside the newly created directory, once the command is completed, one would see something like this:

rails_ls.jpg

The two directories of importance at present are “app” and “config.” The “app” directory contains the subdirectories having the files implementing the Controller and View logic of the application. At present these subdirectories contain nothing of importance. Hence the application is just skeletal. To make this skeletal structure work, a Controller is required. How to create a Controller is covered in the next step.

Creation of the Controller

Since the Controller orchestrates the application, without the Controller, it would be nearly impossible to make the application work. That’s true with RoR. So to create the Controller, RoR provides a command called generate. In reality, the generate command is a Ruby script in the “script” directory. This command has many more functions, which becomes the center point of the next step. For now, to create a controller named ‘Say’ in the “demo” (or whatever may be the application name) directory, the following command has to be issued:

ruby script/generate controller Say

The generate command takes the type of the MVC component as the first argument and the name of the component as the second argument. Here the type (constituent) of the MVC component is Controller and the name of the Controller is Say. On giving the command RoR responds with:

rails_controller.jpg

The significant aspect of the output is the three files and a directory that are generated: the directory “say” under app/view directory, the say_controller.rb under app/controllers directory and say_helper.rb under the app/helpers directory. Let’s leave the “say” directory for now. The Controller say_controller.rb is the Controller of this application. Here also CoC comes into the picture. The Controller is suffixed with “_controller”. The next file is the say_helper.rb. It provides the services required by the Controller. If one looks at the say_controller.rb, the code would be something like this:

class SayController < ApplicationController

end

The above code means that the SayController is inheriting from the ApplicationController class. Each control action would have to be defined as a method of the SayController class. So to create a control action (or controller) called hello, one would have to define a method called hello as a member method of SayController class thus:

    class SayController < ApplicationController

def hello

end

end

Now the Controller for the application demo is created. Though it does nothing much, it’s a beginning. The next step is creating the View component because without a corresponding View, the Controller’s orchestration proves nothing.

Implementing the View

To implement the View, RoR provides a templating technique in the form of RHTML, using which, the Ruby statements can be embedded into the HTML pages. To create the View, first an RHTML file is created. The name of the file has to be the same as that of the Controller. For example, to create a View for the Controller (or control action) hello, an RHTML file with the same name has to be created inside the app/view folder of the application. So the required RHTML file would be hello.rhtml. To make it more clear following could be the content of the file:

<html>

<head>

<title>Hello, Rails!</title>

</head>

<body>

<h1>Hello from Rails! The time now is<%=Time.now%> </h1>

</body>

</html>

That completes the View part of the RoR.

Configuring the database

To configure a database connection for the application is as easy as changing two to three parameters in a file. But before that following things have to be done:

First, the database (or tablespace in Oracle’s case) has to be suffixed with  _development for development purposes, _test for testing purposes and _production for release purposes. For example, if the database name (for MySQL) is scm, then scm_development should be the name of database used for development, scm_test for debugging and scm_production for the release version of the database.

Then, the pure Ruby-based database driver is required for connectivity, otherwise connection time errors will be thrown during the database configuration step.

With these points in mind, let’s look at database configuration using the database.yml file. When the application is created, RoR creates a database.yml file. The required database configuration has to be done here. Typically any database.yml will look like this:

development:

adapter: mysql

database: book_development

username: root

password:

host: localhost

The above configuration is for development purposes. That’s all for database configuration.

Starting the Server

The server for RoR comes built into each application. The server resides inside the “scripts” folder. To start the server the command is as follows:

ruby script/server

and the rails would give the something like the following output:

=> Rails application started on http://0.0.0.0:3000

[2005-02-26 09:16:43] INFO WEBrick 1.3.1

[2005-02-26 09:16:43] INFO ruby 1.8.2 (2004-08-24) [powerpc-darwin7.5.0]

[2005-02-26 09:16:43] INFO WEBrick::HTTPServer-start: pid=2836 port=3000

Ignore the dates. Just look at the port. It is 3000., and 0.0.0.0 is taken as the server address. It is the equivalent of localhost. Now to launch the application the following has to be typed at the address bar of any browser:

http://localhost:3000/demo/say/hello

The interesting aspect is how the URL is formed. It says nothing about RHTML or the controller file. Instead it is using the name that we passed as a parameter to the generate script and the function created inside the controller class. In essence, the URL is of the form:

http://<host>:<port>/<app_name>/<controller_name>/<name_of_the_controller
_method>

Pictorially it is:

image001.jpg

That completes the steps involved in creating a RoR application. In the next section, I will be implementing a CRUD form.

Rails in the Real World 

Since this is the first discussion of RoR, I won’t be presenting a heavy duty example. However, the example to be presented will show the ease of development in RoR. So the example will be based on the Customer Order example I used in the section about MVC. The example will do the following:

1. Provide a form for entering the order details.

2. Provide a list view of all the orders placed.

3. Provide a form for modifying the data.

4. Provide a delete option for a specified order.

Before beginning the development, a database and table must be created because I will be using MySQL. There are certain conventions to be followed for the naming of the table and its fields:

  • The table name should be plural, i.e. in my case the table name would be Orders.
  • The primary key should be of the type INT (for MySQL tables) and its auto increment attribute should be set to true.
  • Keeping the column names in lower case is recommended.

Keeping these points in mind, here is the table definition (the name of the table is demo_development):

CREATE TABLE `orders` (

`id` INT( 10 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`product_name` VARCHAR( 20 ) NOT NULL ,
`cost` VARCHAR( 10 ) NOT NULL

) TYPE = innodb;

Now let’s create the application. The name of the application is demo. So the command would be:

rails demo

Then change the config directory of the demo directory; the database.yml has to be changed in this way:

development:

adapter: mysql

database: demo_development

username: raj

password:

host: localhost

Next, to create a full-fledged database driven application, give the following command at the root directory of the application i.e. “demo”:

ruby script/generate scaffold order admin

Here the scaffold argument generates boilerplate code for all three components,  Model, View and Controller for the given table (Orders). The name of the controller is optional, though I have given it. This would create the ORM of the table name, the controller of the given name and the RHTMLs for the add, modify, delete and view functions. The name of the table has to be given in singular, otherwise the application would throw an exception when launched. To check what has been created, start the server, and give the following URL at the address bar:

http://localhost:3001/demo/admin

That’s it. RoR creates all the boilerplate code required for CRUD operations. But there are various aspects that have to be understood before an actual application can be built. Starting with the next part, I would be discussing the Model, View and Controller components provided by Ruby-on-Rails.

by A.P.Rajshekhar