Skip to main content

An introduction to Ruby on Rails for DB2 developers

Agile Web development meets DB2

Edd Dumbill (edd@usefulinc.com), Principal, Useful Information Company
Edd Dumbill is chair of the XTech conference on Web and XML technologies, and the principal of the Useful Information Company. Together with Matt Biddulph, he is available for delivering Ruby on Rails training to development teams. Edd has a Weblog called Behind the Times.

Summary:  Learn how to speed your development of DB2®-based Web applications using the Ruby on Rails Web framework.

Date:  22 Jun 2006
Level:  Introductory
Activity:  2884 views

Ruby on Rails is an open source Web framework causing a lot of excitement among Web developers. By supporting agile development techniques and a philosophy of "convention over configuration," it has enabled many developers to radically reduce the time and pain involved in creating Web applications.

Because Rails emerged from the open source world, until recently you had to use MySQL or PostgreSQL to work with it. Now that IBM has released a DB2 adapter for Rails, it's possible to write efficient Web applications on top of your existing DB2 database investment.

This article highlights some of the things that makes Rails exceptional, explains how to get going with Rails and DB2, and leads you through your first Web application in Rails.

What's special about Ruby on Rails?

Ruby on Rails, or "Rails" for short, hasn't risen to fame in the Web development world without reason. Rails was originally conceived out of real-world requirements, having emerged through the refactoring of a large Web application that its author, David Heinemeier-Hansson, was writing. This origin means that Rails is optimized to achieve its goals, rather than being the result of an abstract API architecture, with all the tendencies such things have to sprawl.

One of the biggest time-savers in Rails is convention over configuration. Simple things such as naming your data model class with the same name as the corresponding database table means that you don't have to write needless mapping code, as do techniques such as always using "id" as the primary key name. Of course Rails provides get-outs and overrides, but the idea is only to use these when necessary.

As a framework, Rails implements the model-view-controller (MVC) architecture. The MVC design pattern separates the component parts of an application:

  • A model encapsulates data that the application manipulates, plus domain-specific logic.
  • A view is a rendering of the model into the user interface.
  • A controller responds to events from the interface and causes actions to be performed on the model.

The MVC pattern allows rapid change and evolution of the user interface and controller separate from the data model, making it eminently suitable for Web application programming.

Rails also enthusiastically embraces test-driven development. This is a core part of agile software development methodology, and enables confident evolution of an application. Rails has support for three different types of testing:

  • Unit testing: Operating on the model.
  • Functional testing: Operating on individual controllers and their views.
  • Integration testing: Enabling application-wide testing.

Though many people accept that test-driven development is a good idea, it is often ignored because of the inconvenience of writing tests. Rails leaves you few excuses, as it brings tests right into the heart of the application environment.

Rails as a platform

Everything in Rails is based around the Ruby programming language. If you don't know Ruby, don't worry. It won't be too far from other languages you've come across, such as Python, Perl, or Java. Though a knowledge of Ruby is going to be very useful as you continue to develop in Rails, you don't need to know much to get started.

In production, Rails interfaces well with Web servers such as Apache and Lighttpd. In development, it ships with a Ruby Web server so you don't need to fiddle around before getting started.

Rails requires no special file formats or integrated development environments (IDEs), you can get started with it simply with a command line prompt and a text editor. That said, there are various IDEs now with Rails support such as RadRails, which is a Rails environment for Eclipse.

Install Rails and the DB2 adapter

You can run Rails anywhere that you can run the Ruby interpreter. For Windows, you can download a standalone package from the Rails Web site rubyonrails.org. For Linux, the best way is to use the Ruby "gem" package manager to install Rails. Install Ruby in the usual way for your Linux system, then download RubyGems. Unpack it, then run with:

# ruby setup.rb

When the gem system is installed, you can install Rails over the Internet:

# gem install rails --include-dependencies

While some Linux package managers do include Rails, not all of them have up-to-date installations at this point.

If you don't have DB2 installed on the machine you intend to use, then you can take advantage of the IBM Starter Toolkit, which includes both Rails and a DB2 installation in one. This is available for Windows right now, and will shortly be available for Linux.

The DB2 adapter is available from alphaWorks in the "DB2onRails_Vx.x_Source.zip" package.

To install it, follow these instructions. This article uses Linux path separators ('/') by convention, so on Windows you'll need to adjust accordingly.

  1. Download and unpack DB2onRails_Vx.x_Source.zip.
  2. Copy the adapter/ibm_db2_adapter.rb file to the activerecord-1.14.2/lib/active_record/connection_adapters directory (you can find this inside the site_ruby/1.8 directory in your Ruby installation).
  3. Build the adapter binary extension (ibm_db2.dll for Windows, ibm_db2.so for Linux).
    	$ cd rubydb2
    	$ rake lib
    

    • On Windows, copy the ibm_db2.dll file to the lib\ruby\site_ruby\1.8\i386-msvcrt directory in your Ruby installation.
    • On Linux, copy the ibm_db2.so file to the /usr/lib/ruby/1.8/i486-linux (or similar) directory.
  4. Amend the activerecord-1.14.2/lib/active_record.rb file (adjust this path to the right place for your Rails installation), and add ibm_db2 to the end of the RAILS_CONNECTION_ADAPTERS array. It should then read something like this:
    RAILS_CONNECTION_ADAPTERS = %w( mysql postgresql sqlite firebird
    sqlserver db2 oracle sybase openbase ibm_db2 )

Now you should be ready to get going with your first Rails application.

Create a database for your Rails application

For the purposes of this article, it is assumed you're creating a new application from scratch. This lets you proceed along Rails' "golden path" of convention over configuration. Legacy databases can be put on Rails using a combination of Rails configuration and sometimes database views, but that's outside of the scope of this article.

For every application, Rails requires by default the specification of three different databases:

  • A development database, which you code against.
  • A test database, used for testing. The test database is volatile.
  • A production database, used when the application is deployed.

The example application you're going to write is to underpin a directory of software resources. I run a Web page that lists open source bug tracking software, which is currently just managed as a text page. I've decided it would be better to have the directory in a database, in order to be able to do more with the data in the future.

Use the DB2 Control Center to create three databases: SOFTD_D, SOFTD_T, and SOFTD_P for the development, testing, and production databases respectively. Unless you have a good reason not to, select the UTF-8 codeset for the database. This sets you up for internationalization from the start. The Control Center issues three commands like these (the exact command varies depending on your locale):

CREATE DATABASE softd_d AUTOMATIC STORAGE YES  ON '/home/db2inst1'
USING CODESET UTF-8 TERRITORY GB COLLATE USING SYSTEM PAGESIZE 4096;

CREATE DATABASE softd_t AUTOMATIC STORAGE YES  ON '/home/db2inst1'
USING CODESET UTF-8 TERRITORY GB COLLATE USING SYSTEM PAGESIZE 4096;

CREATE DATABASE softd_p AUTOMATIC STORAGE YES  ON '/home/db2inst1'
USING CODESET UTF-8 TERRITORY GB COLLATE USING SYSTEM PAGESIZE 4096;

Create the Rails application

Now you've got a database to work against, it's time to create the Rails application. Open up a command prompt in your work directory and create the application:

$ rails softdir

This creates a number of directories and files in the softdir directory. The first thing you need to do is tell Rails how to speak to our database. Edit the config/database.yml file and set it up as shown below.

development:
	adapter: ibm_db2
	database: softd_d
	username: db2inst1
	schema: db2inst1
	password: yourpassword
	host: localhost
	port: 50000

	# Warning: The database defined as 'test' will be erased and
	# re-generated from your development database when you run 'rake'.
	# Do not set this db to the same as development or production.
test:
	adapter: ibm_db2
	database: softd_t
	username: db2inst1
	schema: db2inst1
	password: yourpassword
	host: localhost
	port: 50000

production:
	adapter: ibm_db2
	database: softd_p
	username: db2inst1
	schema: db2inst1
	password: yourpassword
	host: localhost
	port: 50000

You need to replace the host, port, username, and password according to your DB2 installation, if they differ from the defaults given here. You must also select a suitable schema for connection, here just the default of a schema matching the connecting username is given.

All that remains now is to start the development instance of your Web application, to check that all is OK.

In your Rails app directory, run ./script/server. You should see the following output as the built-in Web server starts:

=> Booting WEBrick...
=> Rails application started on http://0.0.0.0:3000
=> Ctrl-C to shutdown server; call with --help for options
[2006-06-10 05:12:56] INFO  WEBrick 1.3.1
[2006-06-10 05:12:56] INFO  ruby 1.8.4 (2005-12-24) [i486-linux]
[2006-06-10 05:12:56] INFO  WEBrick::HTTPServer#start: pid=3311 port=3000

Direct your Web browser to http://localhost:3000/ (or the hostname of your development box, if you're not running a local desktop) and you should see the welcome message below.


Figure 1. Rails welcome message
Rails welcome screen

Create your first model

Now that the database is up and running, you can start creating models. For your bug tracking software list, the most import model for you is that describing a software project. The table below shows a first attempt at the data you want to store.


Table 1. Data to store
FieldType
NameString
DescriptionText
HomepageString
LicenseString
OpensourceBoolean
NotesText

As you read that table you were probably composing the necessary SQL to create it in your mind's eye. However, the approach in Rails is to avoid writing SQL commands when at all possible. This encourages a certain degree of database independence, it certainly makes an application more readable, and plays an important part in a feature called "migrations."

Migrations recognize that a database structure evolves as an application does, and there needs to be an ordered way to roll forward and backwards in the same way that version control allows for software.

The best way to learn is by doing, so create the model for your projects table. From the command prompt, run the generate script to create a model.

$ ./script/generate model Project
exists  app/models/
exists  test/unit/
exists  test/fixtures/
create  app/models/project.rb
create  test/unit/project_test.rb
create  test/fixtures/projects.yml
create  db/migrate
create  db/migrate/001_create_projects.rb

Rails has added all the infrastructure required for your first model:

  • A class definition in app/models/
  • Test code in test/unit/
  • Test data (fixtures) in test/fixtures/
  • A migration to create the table in db/migrate/

To define the table, edit db/migrate/001_create_projects.rb as shown below.

class CreateProjects < ActiveRecord::Migration
  def self.up
   create_table :projects do |t|
       t.column "name", :string, :null => false
       t.column "description", :text, :null => false
       t.column "homepage", :string
       t.column "license", :string
       t.column "opensource", :boolean, :null => false
       t.column "notes", :text
       t.column "updated_on", :timestamp
       t.column "created_on", :timestamp
     end
   end

   def self.down
     drop_table :projects
   end
end

Now run the migration by invoking the following:

$ rake migrate
(in /disk2/home/edd/work/softdir)
== CreateProjects: migrating ==============================================
-- create_table(:projects)
-> 0.8660s
== CreateProjects: migrated (0.8660s) =====================================

Figure 2 shows the result of the migration. Rails has created a SCHEMA_INFO table to keep track of the migrations, and added the PROJECTS table. The updated_on and created_on timestamps have been added to keep a track of changes in the database, you will see later on that Rails updates these for free. Rails also gives you a primary key for free, the ID column. As you'll see later, you can suppress this if you need.


Figure 2. The PROJECTS table, viewed from the DB2 Control Center
DB2 Control Center

You may also notice the default naming conventions in Rails. People tend either to love or hate them, but it's a lot easier to love them. In general, Rails aims for a natural (English) language feel to its directives, and the first place you meet this is in the pluralization connected with model names.

  • Database table name: projects
  • Model class name: Project
  • Model source file: app/models/project.rb
  • Test data fixture file: test/fixtures/projects.rb

Create the user interface

With the first model created, it's time to add a controller and view so some basic manipulation of the application is possible. Again, Rails' generator script comes in handy here, by providing a quick way to write the necessary boilerplate code. Craft some code for the administration of the projects list.

$ ./script/generate scaffold Project Admin
			

The scaffolding creates basic code to support create, update, delete (CRUD) operations on the model. Visit http://localhost:3000/admin to see the interface where you can add, edit, and remove records.


Figure 3. The editing interface
Editing interface

Figure 4. The record list
Record list

Figure 5. The record view
Record view

While functional, these templates are barely usable and are only intended to provide you with a starting point.

To begin with, edit app/views/admin/_form.rhtml to make the form more usable by making the text boxes a workable size, and removing the controls for the timestamps, as Rails updates these automatically for you.

<%= error_messages_for 'project' %>

<!--[form:project]-->
<p><label for="project_name">Name</label><br/>
<%= text_field 'project', 'name'  %></p>

<p><label for="project_description">Description</label><br/>
<%= text_area 'project', 'description', :rows => 3, :cols => 60  %></p>

<p><label for="project_homepage">Homepage</label><br/>
<%= text_field 'project', 'homepage', :size => 60  %></p>

<p><label for="project_license">License</label><br/>
<%= text_field 'project', 'license', :size => 10  %></p>

<p><label for="project_opensource">Opensource</label><br/>
<%= check_box 'project', 'opensource'  %></p>

<p><label for="project_notes">Notes</label><br/>
<%= text_area 'project', 'notes', :rows => 3, :cols => 60  %></p>
<!--[eoform:project]-->

The RHTML files use embedded Ruby mixed with HTML. The instructions such as text_field are helpers provided by Rails that generate HTML forms for processing by the controller.

The development server reacts instantly to source changes, so reload the editing interface and try it out.

You will notice that it's possible to enter blank data for things you do not wish to be empty, such as the name of a project. To fix this, you need to add just a little more into the model class. Take a look at app/models/project.rb and add in these constraints, shown in bold below:

class Project < ActiveRecord::Base
	validates_presence_of :name
				validates_presence_of :description
end

Notice how little code is required for the data binding. This is because Rails relies on naming conventions and database introspection until you tell it otherwise.

Finally, you can test the effects of this validation by attempting to enter an empty name. You should see the error shown in something similar to that below.


Figure 6. Rails validation error reported to the user
Rails validation error reported to the user

What does everything do?

  • app/models/: Contains the models, which encapsulate application business logic.
  • app/views/layouts/: Contains master templates for each controller.
  • app/views/controllername/: Contains templates for controller actions.
  • app/helpers/: Contains helpers, which you can write to provide more functionality to templates.
  • components/: Used for bundles of application functionality you might want to reuse (an advanced feature).
  • config/: Contains application configuration, plus per-environment configurability.
  • db/: Contains a snapshot of the database schema and migrations.
  • log/: Contains a log for each environment (your first port of call if things aren't going as expected).
  • public/: Contains all static files, such as images, javascripts, and style sheets.
  • script/: Contains Rails utility commands.
  • test/: Contains test fixtures and code.
  • vendor/: Contains add-in modules. If you 'freeze' Rails, the system Rails gems are copied in here so you always know exactly which version you are running.

How does a request reach the code?

The mapping of an incoming browser request to the code that actually does the work in Rails is handled by routes, as stored in the config/routes.rb file.

By default, this mapping is of the form /controller/action/id, such as in URLs similar to /admin/edit/100 that you have seen while editing the project list. Rails finds the required controller, then looks for any method it has corresponding to the action name. Finally, it displays the template found in apps/views/controller/action.rhtml.

The value of id and any additional CGI query parameters are all passed into the params hash, available to the controller and the views.

Add another model

Almost all useful database applications require more than one model, and Rails provides some very powerful facilities for dealing with relationships between tables.

For your bug tracker list to be useful to users, you need a way of enumerating which facilities each tracker provides, such as an email interface, version control system integration, or a public Web interface. These facilities can be tracked in another model.

$ ./script/generate model Facility

Edit the migration db/migrate/002_create_facilities.rb and add in the definition for a facility.

class CreateFacilities < ActiveRecord::Migration
  def self.up
    create_table :facilities do |t|
    t.column :name, :string
  end
end

  def self.down
    drop_table :facilities
  end
end

Migrate the database with rake migrate and you're set. You can quickly scaffold a basic editor:

$ rake migrate
$ ./script/generate scaffold Facility facility

Point your browser at http://localhost:3000/facility/ and add a few entries, such as shown below.


Figure 7. Example facilities
Example facilities

What remains now is to be able to assign facilities to projects, through the use of a join table. Because you don't need an associated model, you just need to generate a migration:

./script/generate migration AddFacilitiesProjectsLink

Edit it to create the join table, suppressing the auto-supplied id field:

class AddFacilitiesProjectLink > ActiveRecord::Migration
  def self.up
    create_table(:facilities_projects, :id => false) do |t|
      t.column "facility_id", :integer, :null => false
      t.column "project_id", :integer, :null => false
    end
  end

  def self.down
    drop_table :facilities_projects
  end
end

Lastly, you amend the models to indicate the relationships. In project.rb, add:

has_and_belongs_to_many :facilities

In facility.rb, add:

has_and_belongs_to_many :projects

Again, thanks to convention, no more definition of column and table names is required. If you run the command line access to your Rails application, you see each model has a corresponding new method:

$ ./script/console
Loading development environment.
>> Project.find(:first).facilities
=> []
>> Facility.find(:first).projects

Finally, you must create the editing and display interfaces for the links between the tables. Edit the app/views/admin/_form.rhtml template an add in a new user interface element as shown below.

<p><label for="project[facility_ids][]">Facilities</label><br />
<%= select_tag('project[facility_ids][]',
options_from_collection_for_select(Facility.find(:all, :order => 'name'),
'id', 'name', @project.facilities.collect {|f| f.id}),
:multiple => true
)%></p>


Figure 8. Editing interface with facilities selector
Editing interface with facilities selector

As you can see, this creates a list choice for linking facilities to projects, and populates it by default with the existing links. Naming conventions again ensure that Rails is responsible for updating the link table.

If you examine the development log in logs/development.log, you see the SQL Rails is executing in response to your actions.

Summary

As a result of following this article, you now hopefully have your first Rails application up and running against DB2. This article has only been able to touch on the aspects of Rails, but the benefits of its pragmatic approach to Web development to productivity ought to be clear.

To learn more, you can follow one of the extended tutorials available from the Ruby on Rails Web site, or buy a Rails book. I heartily recommend "Agile Web Development with Rails" (Pragmatic Programmers), found in the Resources section.

For more help with Rails integration with DB2, watch the movies on the alphaWorks site (found in the Resources section) and participate in the DB2 Rails Starter Kit forum.



Download

DescriptionNameSizeDownload method
Example code developedsoftdir.tar.gz48KB HTTP

Information about download methods


Resources

Learn

Get products and technologies

  • RadRails:Is an IDE for Rails based on Eclipse.

  • IBM's alphaWorks site hosts the DB2 Rails Starter Kit. Help is available from the related forums.

  • Build your next development project with IBM trial software, available for download directly from developerWorks.

Discuss

About the author

Edd Dumbill is chair of the XTech conference on Web and XML technologies, and the principal of the Useful Information Company. Together with Matt Biddulph, he is available for delivering Ruby on Rails training to development teams. Edd has a Weblog called Behind the Times.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Information Management, Open source
ArticleID=132758
ArticleTitle=An introduction to Ruby on Rails for DB2 developers
publish-date=06222006
author1-email=edd@usefulinc.com
author1-email-cc=

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Special offers