1. Ruby On Rails
• Introduction
• What is Rails?
Ruby on Rails, often shortened to Rails or RoR, is an open source web application
framework for the Ruby programming language. It is intended to be used with an Agile
development methodology which is used by web developers for rapid development.
“In 1981, when I started working on Unix, I remember being blown away
by the power of the command-line pipes-and-filters paradigm. I’ve worked
with lots of programming environments since then, but none of them give
me that feeling of being able to write a solution so well that working code
just flew off of my fingers. Until now: Ruby on Rails achieves for web
programming the same sort of conceptual leap that Unix made for file-
handling. You’ve got to try it!”
− Bruce Perens
Even though there are dozens of frameworks out there, and most of them have been
around much longer than Rails, the eye-catching about RoR is one can develop a web
application at least ten times faster with Rails than you can with a typical Java
framework that to without making any sacrifices in the quality of your application!
• How is this possible? (RoR Philosophy)
Part of the answer lies in the Ruby programming language. Rails takes full advantage of
Ruby. The rest of the answer is in two of Rails' guiding principles: DRY – Don’t Repeat
Yourself and CoC - Convention over Configuration.
DRY – Don’t Repeat Yourself means one write fewer lines of code to implement one’s
application. Keeping your code small means faster development and fewer bugs, which
makes one’s code easier to understand, maintain, and enhance. According to "Don't
repeat yourself", information is located in a single, unambiguous place. For example,
using the ActiveRecord module of Rails, the developer does not need to specify database
column names in class definitions. Instead, Ruby on Rails can retrieve this information
from the database based on the class name.
Convention over configuration means an end to verbose XML configuration files--there
aren't any in Rails! Instead of configuration files, a Rails application uses a few simple
programming conventions that allow it to figure out everything through reflection and
discovery. One’s application code and one’s running database already contain everything
that Rails needs to know!
38
2. Ruby On Rails
• Short History
Ruby on Rails was extracted by David Heinemeier Hansson
from his work on Basecamp, a project management tool by
37signals (a web application company). Heinemeier Hansson
first released Rails as open source in July 2004, but did not
share commit rights to the project until February 2005. In
August 2006 the framework reached a milestone when Apple
announced that it would ship Ruby on Rails with Mac OS X
v10.5 "Leopard", which was released in October 2007. David Heinemeier Hansson, the creator
• What is Ruby?
Ruby is a dynamic, reflective, general purpose object-oriented
programming language that combines syntax inspired by Perl
with Smalltalk-like features. Ruby originated in Japan during
the mid-1990s and was initially developed and designed by
Yukihiro "Matz" Matsumoto. It is based on Perl, Smalltalk,
Eiffel, Ada, and Lisp.
Ruby supports multiple programming paradigms, including
functional, object oriented, imperative and reflective. It also
has a dynamic type system and automatic memory
management; it is therefore similar in varying respects to
Python, Perl, Lisp, Dylan, and CLU. Yukihiro Matsumoto, the creator of Ruby.
The standard 1.8.7 implementation is written in C, as a single-pass interpreted language.
There are a number of complete or upcoming alternative implementations of the Ruby
language, including YARV, JRuby, Rubinius, IronRuby, and MacRuby, each of which
takes a different approach, with JRuby and IronRuby providing just-in-time compilation.
The official 1.9 branch uses YARV, as will 2.0 (development), and will eventually
supersede the slower Ruby MRI.
• Why Ruby?
Ruby is becoming popular exponentially in Japan and now in US and Europe as well.
Following are greatest factors:
• Easy to learn
• Open source (very liberal license)
• Rich libraries
• Very easy to extend
• Truly Object-Oriented
• Less Coding with fewer bugs
• Helpful community
38
3. Ruby On Rails
• Technical overview
Like many contemporary web frameworks, Rails uses the Model-View-Controller (MVC)
architecture pattern to organize application programming.
Ruby On Rails
Web Application
Ruby on Rails features several tools intended to make commonplace development tasks
easier "out of the box". Rails provides scaffolding which can automatically construct some
of the models and views needed for a basic website. A simple ruby web server (WEBrick)
and Rake build system are also included. By including these common tools with the Rails
framework, a basic development environment is in effect provided with all versions of the
software.
38
4. Ruby On Rails
Ruby on Rails relies on a web server to run it. Mongrel is generally preferred over WEBrick
at the time of writing but it can also be run by Lighttpd, Abyss, Apache (either as a module -
Passenger for example - or via CGI, FastCGI or mod_ruby), and many others.
Rails is also noteworthy for its extensive use of JavaScript libraries Prototype and
Script.aculo.us for Ajax. Rails initially utilized lightweight SOAP for web services; this was
later replaced by RESTful web services.
Since version 2.0, Ruby on Rails by default offers both HTML and XML as output formats.
The latter is the facility for RESTful web services.
• Framework structure
38
5. Ruby On Rails
A framework is a program, set of programs, and/or code library that writes most of
application for reusability. When is framework used, programmer’s job is to write the parts
of the application that make it do the specific things needed.
While writing Rails application, programmer just leave aside configuration and other
housekeeping chores and he just need to perform three primary tasks
• Describe and model application's domain: The domain is the universe of application.
The domain may be music store, university, dating service, address book, or hardware
inventory. So here, figure out what's in it, what entities exist in this universe and how the
items in it relate to each other. This is equivalent to modeling database structure to keep
the entities and their relationship.
• Specify what can happen in this domain: The domain model is static; now it’s time to
get dynamic. Addresses can be added to an address book. Musical scores can be
purchased from music stores. Users can log in to a dating service. Students can register
for classes at a university. Here programmer needs to identify all the possible scenarios
or actions that the elements of domain can participate in.
• Choose and design the publicly available views of the domain: At this point, one can
start thinking in Web-browser terms. Once it is decided that the domain has students,
and that they can register for classes, a welcome page, a registration page, and a
confirmation page etc. can be envisioned. Each of these pages, or views, shows the user
how things stand at certain point.
Based on the above three tasks, Ruby on Rails deals with a Model/View/Controller (MVC)
framework.
• Ruby on Rails MVC framework:
The Model View Controller principle divides the work of an application into three
separate but closely cooperative subsystems.
38
6. Ruby On Rails
ActionView and ActionController are bundled together under ActionPack.
ActiveRecord provides a range of programming techniques and shortcuts for manipulating
data from an SQL database. ActionController and ActionView provide facilities for
manipulating and displaying that data. Rails ties it all together.
• Ruby on Rails Directory Structure
When the rails helper script is used to create an application, it creates the entire directory
structure for the application. Rails knows where to find things it needs within this
structure, so programmer don't have to tell it.
Here is a top level view of directory tree created by helper script at the time of
application creation. Except for minor changes between releases, every Rails project will
have the same structure, with the same naming conventions. This consistency gives a
tremendous advantage; of quickly moving between Rails projects without relearning the
project's organization.
A directory structure for any rails application is as shown follows:
38
7. Ruby On Rails
demo/
..../app
......../controller
......../helpers
......../models
......../views
............../layouts
..../components
..../config
..../db
..../doc
..../lib
..../log
..../public
..../script
..../test
..../tmp
..../vendor
README
Rakefile
• Purpose of each directory
• app : This organizes application components. It's got subdirectories that hold
the view (views and helpers), controller (controllers), and the backend
business logic (models).
• app/controllers: The controllers subdirectory is where Rails looks to find
controller classes. A controller handles a web request from the user.
• app/helpers: The helpers subdirectory holds any helper classes used to assist
the model, view, and controller classes. This helps to keep the model, view,
and controller code small, focused, and uncluttered.
• app/models: The models subdirectory holds the classes that model and wrap
the data stored in application's database. In most frameworks, this part of the
application can grow pretty messy, tedious, verbose, and error-prone. Rails
makes it dead simple!
• app/view: The views subdirectory holds the display templates to fill in with
data from application, convert to HTML, and return to the user's browser.
• app/view/layouts: Holds the template files for layouts to be used with views.
This models the common header/footer method of wrapping views. In views,
a layout using the <tt>layout :default</tt> is defined and a file named
default.rhtml is created. Inside default.rhtml, <% yield %> is called to render
the view using this layout.
• components : This directory holds components tiny self-contained
applications that bundle model, view, and controller.
• config: This directory contains the small amount of configuration code that an
application will need, including database configuration (in database.yml),
Rails environment structure (environment.rb), and routing of incoming web
requests (routes.rb). One can also tailor the behavior of the three Rails
environments for test, development, and deployment with files found in the
environments directory.
38
8. Ruby On Rails
• db: Usually, Rails application will have model objects that access relational
database tables. Programmer can manage the relational database with scripts
you create and place in this directory.
• doc: Ruby has a framework, called RubyDoc, that can automatically generate
documentation for code created. RubyDoc can be assisted with comments in
code. This directory holds all the RubyDoc-generated Rails and application
documentation.
• lib: Libraries are placed here, unless they explicitly belong elsewhere (such as
vendor libraries).
• log: Error logs go here. Rails creates scripts that help manage various error
logs. Separate logs for the server (server.log) and each Rails environment
(development.log, test.log, and production.log) is created
• public: Like the public directory for a web server, this directory has web files
that don't change, such a s JavaScript files (public/javascripts), graphics
(public/images), stylesheets (public/stylesheets), and HTML files (public).
• script: This directory holds scripts to launch and manage the various tools
that will be used with Rails. For example, there are scripts to generate code
(generate) and launch the web server (server).
• test: The tests programmer write and those Rails creates for programmer all
go here. Subdirectory for mocks (mocks), unit tests (unit), fixtures (fixtures),
and functional tests (functional) is created.
• tmp: Rails uses this directory to hold temporary files for intermediate
processing.
• vendor: Libraries provided by third-party vendors (such as security libraries
or database utilities beyond the basic Rails distribution) go here.
Apart from these directories there will be two files available in demo directory.
• README: This file contains a basic detail about Rail Application and
description of the directory structure explained above.
• Rakefile: This file is similar to Unix Makefile which helps with building,
packaging and testing the Rails code. This will be used by rake utility supplied
along with Ruby installation.
• Road map to the features of Rails
38
9. Ruby On Rails
1. High productivity and reduced development time
2. How does Rails do it?
3. Rails components
4. General features
5. Active Record
6. Action Pack
7. Action Mailer
8. Action Web Service
• High Productivity and Reduced Development Time
At the feature level, Ruby on Rails doesn't offer anything new. Existing web application
frameworks have done it all before. What's the big deal, then? The difference lies in how
Ruby on Rails does it. When simple web application is finished in days instead of weeks
and more complicated web application in weeks instead of months, people notice!!
This newfound attention would be short-lived if the resulting web apps were messy and
hard to maintain or extend. Fortunately Ruby on Rails actually facilitates good
programming practices, which leads to well-factored and easily maintained code.
The attention would also be short-lived if Ruby on Rails had no depth--that is, if once
programmer tried to use it for anything beyond the simplest of web applications, he
suddenly found himself hitting a wall, unable to proceed due to inherent limitations.
Experienced developers who know their way around the Web have repeatedly reported
that this is not the case with Rails. For example, Tomcat, Ant, and the Servlet API author
James Duncan Davidson recently wrote:
“Rails is the most well thought-out web development framework I've ever
used. And that's in a decade of doing web applications for a living. I've
built my own frameworks, helped develop the Servlet API, and have
created more than a few web servers from scratch. Nobody has done it like
this before. That's not to say they got it all right. It's by no means
"perfect". I've got more than a few nits and picks about how things are put
together. But "perfect" isn't the point. The point is that it gets you up and
going fast and has plenty of depth to keep you going. And Rails does that
very well.”
• How does Rails do it?
38
10. Ruby On Rails
Like a good recipe, Rails helps achieve this new level of productivity by combining the
right ingredients in the right amounts. Here are a few of the most important ingredients
that make Rails what it is.
• Ruby
Much of the power of Rails comes from the Ruby programming language. Ruby's
unique design makes it easy to create domain-specific languages and to do
metaprogramming. Rails takes full advantage of this.
• Full-stack MVC framework
Rails is an MVC (model, view, controller) framework where Rails provides all the
layers and they work together seamlessly. Other frameworks often implement
only part of the solution, requiring the developer to integrate multiple frameworks
into the application and then coerce them into working together. (For example, a
Java developer might use Hibernate, Struts, and Tiles to get full MVC support.)
• Convention over configuration
Convention over configuration means an end to verbose XML configuration
files--in Rails, there aren't any! Instead of XML sit-ups, a Rails application uses a
few simple programming conventions that allow it to figure everything out
through reflection and discovery. For example, Rails uses intelligent reflection to
automatically map database tables to Ruby objects. Application code and running
database already contain everything Rails needs to know.
• Less code
Following the simple Rails programming conventions does more than just
eliminate the need for configuration files. It also means that Rails can
automatically handle myriad lower-level details without programmer having to
tell it to do so. This means that he write fewer lines of code to implement his
application. Keeping code small means faster development and fewer bugs, which
makes code easier to understand, maintain, and enhance.
• Generators
Rails' use of runtime reflection and metaprogramming eliminates much of the
boilerplate code that would otherwise have to create. One can often avoid what
little boilerplate code remains by using the built-in generator scripts to create it
for him. This leaves programmer with more time to concentrate on the code that
really matters-- business logic.
• Zero turnaround time
38
11. Ruby On Rails
The typical development cycle for testing a change to a web app has steps such as
configure, compile, deploy, reset, and test. This is very time consuming. The Rails
development environment has none of this. Programmer simply makes a change
and sees it work. Don't make the mistake of dismissing this as a minor point. It's
hard to overstate how much this improves productivity and helps maintain a
creative flow without interruption.
• Scaffolding
Rails can automatically create a full set of CRUD (Create, Retrieve, Update, and
Delete) operations and views on any database table. This scaffolding can get
programmer up and running quickly with manipulating his database tables. Over
time, he can incrementally replace the generated CRUD operations and views
with his own--presumably much prettier and more functional.
• Rails Components
Rails itself consists of several components, which can be installed and used separately.
They are designed to work together seamlessly, though, and developers almost always
use them together:
• Active Record is the object-relational mapping (ORM) layer that connects business
objects (models) to database tables. It is an implementation of the Active Record
pattern described by Martin Fowler.
• Action Pack is the component that implements both the view and controller portions
of the MVC architecture. The controller part handles incoming requests from the
user's browser and routes them to the correct method of a controller class. The view
part builds the response to send back to the browser using a templating system
similar to that of ASP or JSP.
• Prototype is the component that implements the Ajax, drag-and-drop, and visual
effects within your web pages.
• Action Mailer is the component that handles the sending and receiving of email.
• Action Web Service is the component that makes it easy to add web service APIs to
a web application. Action Web Service supports SOAP, XML-RPC, and WSDL.
• General Features
38
12. Ruby On Rails
Rails has some general and some specific characteristics.
• Web servers
Rails can run on just about any web server that implements CGI. However, the
performance of CGI is notoriously bad, so the preferred deployment of a Rails
application is to use FastCGI. There have been extensive tests of Rails application
deployments with both Apache and LightTPD. There is also a newcomer, SCGI,
which rivals the performance of FastCGI without the complicated setup.
During development, it is usually easiest just to use the WEBrick web server that
comes built-in to Ruby.
• Databases
Rails currently contains support for the following databases:
• MySQL
• PostgreSQL
• SQLite
• SQL Server
• DB2
• Oracle
It takes approximately 100 lines of Ruby code to implement a database adapter, so
adding to this list is not particularly onerous.
• Debugging
When something goes wrong inside Rails web app, it normally gives a pretty
detailed error display in browser (when running in development mode). Often this
is enough to diagnose the problem. When it’s not, there are other options:
• Insert debugging output in controller. For example:
render_text “Got here”
or
render_text “user object = “ + user_obj
• Check the Rails log files. (Use tail on *nix systems.) Look for the files
development.log, production.log, and fastcgi.crash.log. Remember that your
web server has log files, too.
38
13. Ruby On Rails
• Use breakpoints.
• Use a commercial IDE (like ArachnoRuby) with a built-in debugger.
• Custom (pretty) URLs
The default Rails mapping of URLs to controller actions is very simple and easy
to understand. Rails tries very hard to present the user with pretty URLs. Rails
URLs are simple and straightforward, not long and cryptic.
Even so, URLs can be customized bt using Rails routing facility.Rails’ URL
routing is flexible enough to allow create virtually any URL mapping scheme.
The Rails routing facility is pure Ruby code that even allows to use regular
expressions. Because Rails does not use the web server’s URL mapping (like
mod_rewrite in Apache), custom URL mapping will work the same on every web
server.
• Unit testing
Rails actively facilitates unit testing:
• Generating new controllers, models, and scaffolding also creates
corresponding unit test skeletons.
• The strict MVC architecture tends to naturally result in testable actions and
components.
• Rails includes a Rake (Ruby Make) script that will automatically run all your
unit tests.
• Active Record
Active Record is the part of Rails that handles the automatic mapping of database tables
to runtime model objects. It’s the M in MVC, and it is Rails’ implementation of an ORM
layer.
For all the common uses (and some of the not-so-common ones), one will never need to
see or use SQL when accessing or updating database. Active Record’s goal is
specifically to work with relational databases; it does not try to abstract away its SQL
usage. Active Record makes it easy to use custom SQL for those complicated cases
where it is necessary. Even so, it is rarely needed.
• Automated mapping
38
14. Ruby On Rails
Active Record automatically maps tables to classes, rows to objects (instances of
the model classes), and columns to object attributes. For example:
class Product < ActiveRecord::Base
end
automatically maps to the table named products, such as:
CREATE TABLE products (
id int(11) NOT NULL auto_increment,
name varchar(255),
PRIMARY KEY (id)
);
which also automatically creates a name attribute that can be used like this:
my_product = Product.find(:first)
STDOUT.print my_product.name
my_product.name = "New Product Name"
Active Record uses English pluralization rules to map classes to tables. The
model class name is singular and capitalized, while the table name is plural and
lowercased. Examples include:
• An Invoice model class maps to an invoices table.
• A Person model class maps to a people table.
• A Country model class maps to a countries table.
• A SecurityLevel model class maps to a security_levels table.
This singular/plural convention results in code that reads fairly naturally. Notice
how this mapping is intelligent in its use of English pluralization rules. Also the
class names use CamelCase (a Ruby convention), while the table names are all
lowercase with underscores between words.
In cases where this does not work (such as interfacing with a legacy database with
which you have no control over the names), you can also explicitly tell Active
Record what name it should use.
• Associations
Usually, no table stands alone. Most database applications use multiple tables
with specific relationships between those tables. Programmer can tell Active
Record about these relationships in his model classes, and Active Record will
generate a slew of navigation methods that make it easy for code to access related
data. The following models:
class Firm < ActiveRecord::Base
has_many :clients
38
15. Ruby On Rails
has_one :account
belongs_to :conglomorate
end
allow to write code such as this:
my_firm = Firm.find(:last)
STDOUT.print my_firm.account.name
STDOUT.print my_firm.conglomerate.employee_count
for c in my_firm.clients
STDOUT.print "Client: " + c.name + "n"
end
This code will work correctly when the database has a clients and accounts table,
of which each has a name column, and a conglomerates table that has an
employee_count column.
• Validation
Data need to be validated before storing it into database. Active Record contains a
suite of macrolike validators that can be added to model.
class Account < ActiveRecord::Base
validates_presence_of :subdomain, :name, :email_address, :password
validates_uniqueness_of :subdomain
validates_acceptance_of :terms_of_service, :on => :create
validates_confirmation_of :password, :email_address, :on => :create
end
If the built-in validation macros can't do what is needed, user defined validation
methods can always be written
class Person < ActiveRecord::Base
protected
def validate
errors.add_on_empty %w( first_name last_name )
errors.add("phone_number", "has invalid format") unless phone_number
=~ /[0-9]*/
end
def validate_on_create # only runs the first time a new object is saved
unless valid_discount?(membership_discount)
errors.add("membership_discount", "has expired")
end
end
def validate_on_update
errors.add_to_base("No changes have occurred") if
unchanged_attributes?
end
end
person = Person.new("first_name" => "David", "phone_number" => "what?")
person.save # => false (and doesn't do the save)
38
16. Ruby On Rails
person.errors.empty? # => false
person.count # => 2
person.errors.on "last_name" # => "can't be empty"
person.errors.on "phone_number" # => "has invalid format"
person.each_full { |msg| puts msg } # => "Last name can't be emptyn" +
"Phone number has invalid
format"
person.attributes = { "last_name" => "Heinemeier", "phone_number" =>
"555-555" }
person.save # => true (and person is now saved in the database)
If the validate method exists, Rails will call it just before writing any object to the
database. If validation fails, it does not write the object to the database.
validate_on_create and validate_on_update are similar, except that the first is
called only before Rails creates a new record in the database, while the second is
called only when Rails is about to update an existing record.
Conditional validation of attribute can be done as follow:
# Conditional validations such as the following are possible:
validates_numericality_of :income, :if => :employed?
validates_confirmation_of :password, :if => :new_password?
# Using blocks:
validates_presence_of :username, :if => Proc.new { |user|
user.signup_step > 1 }
• Callbacks
As Active Record creates and destroys model objects and creates and updates
them in the database, these events can be monitored in the object's life cycle using
callbacks. Callbacks can be used to handle complex business logic, data can be
modified before Rails writes it to the database (or after Rails reads it from the
database), or just about anything else needed.
For example, the save method that saves a model object's data to the database has
eight callbacks defined:
• before_validation
• before_validation_on_create
• after_validation
• after_validation_on_create
• before_save
• before_create
• after_create
• after_save
This gives fine-grained control over model objects when needed.
38
17. Ruby On Rails
class CreditCard < ActiveRecord::Base
# Strip everything but digits, so the user can specify "555 234 34" or
# "5552-3434" or both will mean "55523434"
def before_validation_on_create
self.number = number.gsub(/[^0-9]/, "") if attribute_present?("number")
end
end
class Subscription < ActiveRecord::Base
before_create :record_signup
private
def record_signup
self.signed_up_on = Date.today
end
end
class Firm < ActiveRecord::Base
# Destroys the associated clients and people when the firm is destroyed
before_destroy { |record| Person.destroy_all "firm_id = #{record.id}" }
before_destroy { |record| Client.destroy_all "client_of = #{record.id}" }
end
• Transactions
A transaction is necessary when there are multiple database operations that all
must succeed before the data in the database can change. If any one of them fails,
the data in database should not change. Transaction blocks are used to ensure this.
transaction do
david.withdrawal(100)
mary.deposit(100)
end
The database-level transaction shown above will prevent the withdrawal from
David's account if the deposit into Mary's account should fail. It will not,
however, protect the david and mary objects from being modified. To do that,
object-level transactions must be used.
Account.transaction(david, mary) do
david.withdrawal(100)
mary.deposit(100)
end
Any failure in this code will roll back the value of the objects as well as the
database.
• Action Pack
Action Pack implements both the view and controller part of Rails.
38
18. Ruby On Rails
• View templates
View templates specify the HTML to return in response to a browser request.
View templates are rhtml files (HTML with embedded Ruby) that are very similar
to ASP or JSP files. Text within <% %> is Ruby code to execute, and text within
<%= %> is also Ruby code to execute and substitute the results back into the
HTML.
<html>
<head>
<title>Invoices for <%= @name
%></title>
</head>
<body>
<% render_partial "invoices_by_customer"
%>
</body>
</html>
By default, Rails will try to find a template whose name matches the currently
executing action. If, for example, Rails executes an edit action in your
InvoiceController, then it will attempt to find and render the view template
.../app/views/invoices/edit.rhtml.
Coder can also build up XML (or HTML) output programmatically in his
controller action. This is useful, for example, for building RSS feeds or
responding to XML-RPC requests. In the following example, xm is an
XmlMarkup object.
xm.em("emphasized") # => <em>emphasized</em>
xm.em { xmm.b("emp & bold") } # => <em><b>emph & bold</b></em>
xm.a("A Link", "href"=>"http://onestepback.org") # => <a
href="http://onestepback.org">A
Link</a>
xm.div { br } # => <div><br/></div>
xm.target("name"=>"compile", "option"=>"fast")
# => <target option="fast" name="compile">
# NOTE: order of attributes is not
specified.
xm.instruct! # <?xml version="1.0" encoding="UTF-8"?>
xm.html { # <html>
xm.head { # <head>
xm.title("History") # <title>History</title>
} # </head>
xm.body { # <body>
xm.comment! "HI" # <!-- HI -->
xm.h1("Header") # <h1>Header</h1>
xm.p("paragraph") # <p>paragraph</p>
} # </body>
} # </html>
• URL routing
38
19. Ruby On Rails
An incoming URL always maps to some action within a controller. A controller is
simply a Ruby class, and each action implemented by the controller is a public
method within the controller class. The default mapping from URL to action
method is (in "Rails-speak"):
/:controller/:action/:id
For example, if Rails received the URL http://myapp.com/invoices/show/37, Rails
would route this to a controller class named InvoicesController and within that
class to a method named show. Rails would also pass the 37 to the method as the
id member of the parameter hash that also holds the values of query parameters
and form fields. The code might look like this:
class InvoicesController
def show
@invoice = Invoice.find(params[:id])
end
end
Because actions are methods grouped within a controller (instead of separate
command objects), they can easily share helper methods.
If the default URL routing does not meet required needs, one can easily specify
his own routing rules, even using regular expressions. Because Rails implements
its own URL routing, there is not need to mess with Apache's mod_rewrite, and
routing rules will work the same under all web servers.
Rails routing rules are Ruby code. Here is an example:
map.connect 'date/:year/:month/:day',
:controller => 'blog',
:action => 'by_date',
:month => nil,
:day => nil,
:requirements => {:year => /d{4}/,
:day => /d{1,2}/,
:month => /d{1,2}/}
With this routing rule, the following URLs are valid:
http://myblog.com/date/2005
http://myblog.com/date/2005/08
http://myblog.com/date/2005/08/01
This rule decomposes a URL containing a date that, perhaps, a blog might use to
display the postings for a particular date. A URL that matches this form will map
to the BlogController class and the by_date method. The parameter hash will
contain values for a four-digit year (/d{4}/ is a Ruby regular expression), a two-
38
20. Ruby On Rails
digit month, and a two-digit day. Further, the month and day are optional; if no
values are present, the parameter hash will contain the default value of nil.
• Filters
Filters allow to run preprocessing code before Rails executes an action and post-
processing code after it completes an action. They are useful for such things as
caching or authentication before calling the action, and compression or
localization of the response after calling an action. The before_filter processing
can either allow the action to be called normally by returning true, or abort the
action by returning false (or by performing a render or redirect operation).
For example:
class BankController < ActionController::Base
before_filter :audit
private
def audit
# record the action and parameters in an audit log
end
end
class VaultController < BankController
before_filter :verify_credentials
private
def verify_credentials
# make sure the user is allowed into the vault
end
end
• Helpers
Helpers are smart methods (functions) that help the view templates generate
HTML. They know to use the model objects and controller classes to create just
the right HTML and, in the process, save a lot of time and effort. Of course, this
also means write fewer lines of code,
Developer can write his own helpers, but several come built into Rails. The
link_to helper, for example, generates anchor tags that create links to controllers
and actions. For example:
<%= link_to "Help", { :action => "help" } %>
creates a link to the help action (method) in the current controller (whatever
controller is handling the current request). The text of the link (what the user sees)
is Help.
<%= link_to "Master Help Index",
{ :controller => "help", :action => "index" }
38
21. Ruby On Rails
%>
This creates a link to the index method in the HelpController class. The text of the
link will be Master Help Index.
<%= link_to "Delete this invoice",
{ :controller => "invoices",
:action => "delete",
:id => @invoice.id },
:confirm => "Are you sure you want to delete this?"
%>
This creates a link to the delete method in the InvoicesController class, and passes
an id parameter (presumably the ID of the invoice to delete). This also uses a
special confirm option that creates JavaScript to pop up a confirmation dialog
letting the user continue or abort.
There is a substantial set of helpers for creating form fields to display and update
values in Active Record model objects, which effectively means values in
database. Assume that database has a people table with columns for the name, the
password, a description, and a Boolean value to indicate whether the person is
single or married. Here's a partial view template with a sampling of form tags that
could be used. (Assume that the variable @person contains a person object read
from a row of the people table.)
<form action="save_person" method="post">
Name:
<%= text_field "person", "name", "size" => 20 %>
Password:
<%= password_field "person", "password", "maxsize" => 20 %>
Single?:
<%= check_box "person", "single" %>
Description:
<%= text_area "person", "description", "cols" => 20 %>
<input type="submit" value="Save">
</form>
That code generates the following HTML:
<form action="save_person" method="post">
Name:
<input type="text" id="person_name" name="person[name]" size="20"
value="<%= @person.name %>" />
Password:
<input type="password" id="person_password" name="person[password]"
size="20" maxsize="20" value="<%= @person.password %>" />
38
22. Ruby On Rails
Single?:
<input type="checkbox" id="person_single" name="person[single] value="1"
/>
Description:
<textarea cols="20" rows="40" id="person_description"
name="person[description]">
<%= @person.description %>
</textarea>
<input type="submit" value="Save">
</form>
There are helpers to create the option tags for a select list from a collection of
rows read from the database; helpers for working with dates, numbers, and
currency; and much more.
There are different categories of built-in helpers, in several actual files. Like,
• Active Record Helpers
• Asset Tag Helpers
• Benchmark Helpers
• Cache Helpers
• Capture Helpers
• Date Helpers
• Debug Helpers
• Form Helpers
• Form Options Helpers
• Form Tag Helpers
• JavaScript Helpers
• Number Helpers
• Pagination Helpers
• Tag Helpers
• Text Helpers
• Upload Progress Helpers
• URL Helpers
• Ajax & JavaScript helpers
Rails integrates the Prototype JavaScript library to implement its browser-side
Ajax support, visual effects, and drag-and-drop abilities.
Rails has a simple, consistent model for how it implements Ajax operations. Once
the browser has rendered and displayed the initial web page, different user actions
cause it to display a new web page (like any traditional web app) or trigger an
Ajax operation:
38
23. Ruby On Rails
• A trigger action occurs. This could be the user clicking on a button or link, the
user making changes to the data on a form or in a field, or just a periodic
trigger (based on a timer).
• The client sends data associated with the trigger (a field or an entire form)
asynchronously to an action handler on the server via XMLHttpRequest.
• The server-side action handler takes some action based on the data, and
returns an HTML fragment as its response.
• The client-side JavaScript (created automatically by Rails) receives the
HTML fragment and uses it to update a specified part of the current page's
HTML, often the content of a <div> tag.
The real beauty is how easy Rails makes it to implement all of this in web
application. The following simple example adds new items to a list:
<html>
<head>
<title>Ajax List Demo</title>
<%= javascript_include_tag "prototype" %>
</head>
<body>
<h3>Add to list using Ajax</h3>
<%= form_remote_tag(:update => "my_list",
:url => { :action => :add_item },
:position => "top" ) %>
New item text:
<%= text_field_tag :newitem %>
<%= submit_tag "Add item with Ajax" %>
<%= end_form_tag %>
<ul id="my_list">
<li>Original item... please add more!</li>
</ul>
</body>
</html>
The Prototype library also provides the Rails developer with a wealth of browser-
side visual effects. Prototype also lets easily add drag-and-drop features to web
application.
• Layouts
Layouts let developer specify a common set of display elements for every page
rendered by a controller. This is typically useful for common headers, footers, and
sidebars. By default, Rails looks in its layouts directory for an rhtml file whose
name matches the controller's name. A layout template might look like this:
<html>
<head>
<title><%= @page_title %></title>
</head>
<body>
<div>The header part of this layout</div>
38
24. Ruby On Rails
<div><%= @content_for_layout %></div>
<div>The footer part of this layout</div>
</body>
</html>
Rails will substitute the HTML that an action renders into the above layout where
it says @content_for_layout.
The controller can also directly specify the name of the layout template to use for
all its actions. This makes it easy to use the same layout for multiple controllers.
Layout templates can also be chosen dynamically at runtime. For example, one
layout for logged-in users and different one for anonymous users
• Components and partials
Components and partials allow modularize view templates.
The simplest are partials, which allow to extract a common piece of a template
into a separate file and then render it from many other templates (or many times
within a single template). Partial templates always have a leading underscore on
their filenames to distinguish them from full templates.
A typical use of a partial is for rendering a collections of items.
<% for ad in @advertisements %>
<%= render :partial => "adview", :locals => { :item => ad } %>
<% end %>
This renders the partial template _adview.rhtml multiple times (once for each ad
in the collection @advertisements). For each rendering, Rails will pass
_adview.rhtml a local variable named item that contains the ad object to use.
Components are similar to partials in that they embed the rendering of another
template within the current template. The difference is that one need to specify the
name of a controller and action, and its template is the one to render and insert
into the current template.
<%= render_component :controller => "calendar", :action => "today" %>
• Scaffolding
Scaffolding allows programmer to get an instant implementation of CRUD
(Create, Retrieve, Update, and Delete) operations on any database table. They're
not pretty, but they do give immediate web-based access to tables. Over time,
CRUD operations and views can be replaced with customized one
Rails supports static or dynamic scaffolding. Static scaffolding physically
generates model, controller, and template files. This lets developer see how it
works and start tweaking this existing code. To generate static scaffolding,
38
25. Ruby On Rails
navigate in the file system to the root of Rails web application and run a
command similar to:
$ ruby script/generate scaffold invoices
This will look for an invoices table in database and use its schema to generate the
model, the controller, all of the view templates, the unit test skeletons, and more.
The command displays a list of all the files that it generates.
The advantage of static scaffolding is that developer gets to see and modify the
generated code. The disadvantage is that if he change database table, the
scaffolding will not reflect those changes. However, if he hasn't modified the
scaffolding, it can be just regenerated.
Dynamic scaffolding does not generate any files. Rails simply creates what it
needs dynamically as web app runs. This means that every time database table is
changed, the scaffolding’s CRUD views immediately show those changes. To
request dynamic scaffolding, place a single line of code in the controller:
class AccountController < ActionController::Base
scaffold :account
end
• Action Mailer
Action Mailer is a simple facility for sending and receiving email in a web application.
Here's a method that sends an email with an attachment:
# send email with attachment
def signup_notification(recipient)
recipients recipient.email_address_with_name
subject "New account information"
from "system@example.com"
attachment :content_type => "image/jpeg", :body => File.read("an-
image.jpg")
attachment "application/pdf" do |a|
a.body = generate_your_pdf_here()
end
end
• Action Web Service
Action Web Service implements server-side support for the SOAP and XML-RPC web
service protocols and makes it easy to create web service APIs and publish them via
WSDL.
38
26. Ruby On Rails
Here is part of the MetaWeblog API as implemented by Typo (open source weblog
software written in Rails):
class MetaWeblogApi < ActionWebService::API::Base
api_method :getRecentPosts,
:expects => [ {:blogid => :string},
{:username => :string},
{:password => :string},
{:numberOfPosts => :int} ],
:returns => [[MetaWeblogStructs::Article]]
api_method :deletePost,
:expects => [ {:appkey => :string},
{:postid => :string},
{:username => :string},
{:password => :string},
{:publish => :int} ],
:returns => [:bool]
end
class MetaWeblogService < TypoWebService
web_service_api MetaWeblogApi
def getRecentPosts(blogid, username, password, numberOfPosts)
articles = Article.find_all(nil, "created_at DESC", numberOfPosts)
articles.to_a.collect{ |c| article_dto_from(c) }
end
def deletePost(appkey, postid, username, password, publish)
article = Article.find(postid)
article.destroy
true
end
end
• Ruby on Rails vs. J2EE
38
27. Ruby On Rails
• Rails and a typical J2EE Web stack
Following figure compares Rails stack to a typical J2EE Web stack comprised of the
Tomcat servlet container, the Struts Web application framework, and the Hibernate
persistence framework.
The fundamental difference between the Rails stack and the components that make up a
common J2EE-based Web application is small. Both have a container in which the
application code will execute; an MVC framework that helps to separate the
application's model, view, and control; and a mechanism to persist data.
• The front controller and URL mappings in Rails and Struts
Struts' ActionServlet and Rails' DispatchServlet are both examples of the Front
Controller pattern; as such, they both provide the same functionality. They accept HTTP
requests, parse the URL, and forward processing of the request to an appropriate action.
In the case of Struts, an action is a class that extends Action; for Rails, it is a class that
extends ActionController. The main difference between the two front controllers is how
they determine the action that processes a particular request.
With Struts, a developer needs to externalize the mappings of specific requests to Action
classes in an XML configuration file. When the ActionServlet is first loaded, it parses
this file and prepares to accept requests. By convention, HTTP requests that end in .do
get redirected to ActionServlet for dispatching to the appropriate Action. The XML in
following figure is a typical mapping. It tells the ActionServlet to forward a request
called deleteOrder.do to controllers.order.DeleteOrderAction for further processing.
38
28. Ruby On Rails
Rails takes a different approach. Instead of relying upon a configuration file to map
requests to actions, it discovers the appropriate action based on the URL requested. As
in following figure , the URL http://localhost/order/delete/4 indicates for Rails to invoke
the delete method on an instance of OrderController and make 4 available as an instance
variable. Rails is smart enough to know that /order maps to a controller class defined in
a file named order_controller.rb. If there is a find method defined in the controller, that
method can be invoked by simply replacing delete with find in the URL.
• The action and the model
In both Rails and Struts, the action acts as a bridge between the front controller and the
model. The developer provides an implementation of an action in order to provide
application-specific processing of a request. The front controller is responsible for
accepting the request and passing it off to a specific action. Following figure illustrates a
basic action hierarchy for Rails and Struts.
Struts requires that the developer extend Action and override execute() in order to
process the request. Generally, each Action class provides a very specific unit of work.
Above figure illustrates three specific actions: SaveOrderAction, DeleteOrderAction,
38
29. Ruby On Rails
and ListOrdersAction. The front controller calls the execute() method and passes it a
number of useful objects, including the HTTP request and response objects. ActionForm
is a class that conveniently transfers and validates form-related input to and from the
view, and ActionMapping contains the configuration information for the mapping.
The execute() method returns an ActionForward object that Struts uses to determine the
component that continues processing the request. Generally, this component is a JSP,
but ActionForward can also point in other actions. Developers must be aware that Struts
will create a single instance of the Action and allow multiple threads to invoke
execute(). This allows for faster request processing, as the framework is not continually
creating new Action instances to handle each request. But because a single object is
shared between multiple threads, developer must observe proper threading
considerations, as other threads are likely to pummel instance variables that hold state in
the action.
In Rails, developer must extend ActionController::Base for the model to participate in
the processing of a request. Rails doesn't pool the instance of the ActionController;
instead, it creates a new instance for each request. While this might have a negative
impact on performance, it makes development easier. Developers need not be concerned
with the threading issues that are present in Struts, and as a result, the session, request,
header, and parameters are all accessible as instance members of the ActionController.
ActionControllers are also a logical place to group all processing of specific domain
logic. While Struts Action classes are fine-grained and provide very specific units of
work, Rails ActionControllers are coarse-grained and model discreet units of work as
methods.
• The persistence frameworks
A persistence framework is used to move data to and from the database in the
application layer. Both Hibernate and Rails persistence frameworks can be classified as
object/relational mapping (ORM) tools, meaning that they take an object view of the
data and map it to tables in a relational database. Both frameworks aim to reduce the
development time associated with working with relational databases. However,
following figure illustrates some fundamental differences in how each is designed and
configured.
38
30. Ruby On Rails
• Hibernate
Hibernate is based on the Data Mapper pattern, where a specific mapper class, the
Session, is responsible for persisting and retrieving data to and from the database.
Hibernate can persist any Java object as long as it conforms to JavaBean
specifications. XML mapping files describe how a class maps to a particular table
in the database, along with any relationships that the class has with other classes.
Following is an example of a Hibernate mapping file. The class tag maps the
Order object to the ORDERS table and has a number of sub tags that describe its
properties, the ID and the order name, and a one-to-many relationship to
models.Item. Then is the Order class itself.
Order.hbm.xml
...
<hibernate-mapping>
<class name="models.Order" table="ORDERS"
dynamic-update="true" dynamic-insert="false"
discriminator-value="null">
<id name="id" column="id" type="java.lang.Long"
unsaved-value="null">
<generator class="identity"/>
</id>
<set name="items" lazy="false" inverse="false"
cascade="none" sort="unsorted">
<key column="id"/>
<one-to-many class="models.Item"/>
</set>
<property name="name" type="java.lang.String"
update="true" insert="true"
access="property" column="name"/>
</class>
</hibernate-mapping>
Order.java
public class Order {
private Set items;
private String name;
private Long id;
public Long getId() { return id;}
38
31. Ruby On Rails
public void setId(Long id) { this.id = id;}
public Set getItems() { return items;}
public void setItems(Set items) { this.items = items; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
• Active Record
Rails' ORM framework is called Active Record and is based upon the design
pattern of the same name. Martin Fowler describes an Active Record as "an object
that wraps a row in a database table or view, encapsulates the database access, and
adds domain logic on that data." In Rails, each domain object extends
ActiveRecord::Base, which provides the CRUD operations.
Active Record doesn't require a mapping file, as Hibernate does; in fact, a
developer working with Active Record doesn't need to code getters or setters, or
even the properties of the class. Through some nifty lexical analysis, Active
Record is able to determine that the Order class will map to the ORDERS table in
the database. Using a combination of Ruby reflection and metaprogramming, the
columns of the table become properties of the object. Accessors and mutators are
also added.
Following example shows the completed code for the Order class. The one line of
code in the class body of Order defines its relationship to the Item object.
has_many is a static method call for which the symbol :items is a parameter.
ActiveRecord uses :items to discover the Item domain object and in turn maps the
Item object back to the ITEMS table in the database.
order.rb
class Order < ActiveRecord::Base
has_many :items
end
The Order class as coded in above provides dozens of class and instance
methods at runtime. Table below offers a partial list of operations and
attributes available on Order:
Class methods Instance methods Attributes
38
32. Ruby On Rails
• find(*args) • add_items • id
• find_by_sql(sql) • build_to_items • name
• exists?(id) • create_in_items
• create(attributes) • find_all_in_items
• update(id, attributes) • find_in_items
• update_all(updates, • has_items?
conditions • items
• delete(id) • items=
• delete_all(conditions) • items_count
• remove_items
• ...
• In summary
While Ruby on Rails is a very new and exciting framework that has generated
considerable interest in the Web development community, the core architecture follows
the basic patterns found in J2EE. It's the philosophical approach to development of Web
applications that sets the two frameworks apart. Rails prefers explicit code instead of
configuration files, and the dynamic nature of the Ruby language generates much of the
plumbing code at runtime. Most of the Rails framework has been created as a single
project and application development benefits from a set of homogeneous components. In
contrast, the typical J2EE stack tends to be built from best-of-breed components that are
usually developed independently of one another, and XML is often used for configuration
and gluing the components together.
• Usage & Support
38
33. Ruby On Rails
• Websites on Rails
• Twitter – Social Networking
• Yellow Pages – Online Directory
• Scribd – Document Sharing
• Hulu – Tv & Video Streaming
• Blinksale – Online Invoicing
• Crunchbase – Company Profiler
• Slideshare – Presentation Sharing
• Well known companies using Rails
• amazon.com
• BBC
• CapGemini
• BPN
• Cisco
• C|Net
• EA (Electronic Arts)
• IBM
• JP Morgan
• NASA
• Oakley
• Oracle
• Siemens
• Google
• Conclusion
Web application frameworks and the developers who use them can be divided into two
distinct categories. At one end of the spectrum, there are the heavy-duty frameworks for the
38
34. Ruby On Rails
"serious" developers, and at the other end there are the lightweight, easy-to-use frameworks
for the "toy" developers. Each of these groups generally regards the other with disdain.
One of the most interesting things is that Rails is attracting developers from both camps.
The high-end developers are tired of the repetitive, low-productivity routine that they have
been forced to endure, while the low-end developers are tired of battling a mess of
unmanageable code when their web apps move beyond the simple. Both of these disparate
groups find that Rails provides sustainable relief for their pain.
At the moment, Ruby on Rails barely captures a tiny percentage of web development
projects. Yet it is rapidly gaining mind share, and many respected software development
leaders have been testing the waters with Rails and publicly singing its praises.
• Appendix
38
35. Ruby On Rails
• Bruce Perens
Bruce Perens is a computer programmer and advocate in the open source community. He
created the Open Source Definition and published the first formal announcement and
manifesto of open source.
• Boilerplate
Boilerplate is any text that is or can be reused in new contexts or applications without
being changed much from the original. In computer programming, boilerplate is the term
used to describe sections of code that have to be included in many places with little or no
alteration. It is more often used when referring to languages which are considered
verbose, i.e. the programmer must write a lot of code to do minimal jobs. The need for
boilerplate can be reduced through high-level mechanisms such as Metaprogramming
(which has the computer automatically write the needed boilerplate text) and Convention
over Configuration (which provides good default values, reducing the need to specify
program details in every project).
• YARV
YARV is a bytecode interpreter that was developed for the Ruby programming language
by Koichi Sasada. The name is an acronym for Yet another Ruby VM. The goal of the
project was to greatly reduce the execution time of Ruby programs.
Since YARV has become the official Ruby interpreter for Ruby 1.9, it is also named KRI
as Koichi's Ruby Interpreter.
• Rubinius
Rubinius is an alternative Ruby implementation created by Evan Phoenix. Based loosely
on the Smalltalk-80 Blue Book design,[1] Rubinius seeks to "provide a rich, high-
performance environment for running Ruby code.
• IronRuby
IronRuby is an upcoming implementation of the Ruby programming language targeting
Microsoft .NET framework. It is implemented on top of the Dynamic Language Runtime,
38
36. Ruby On Rails
a library running on top of CLR 2.0 that provides dynamic typing and dynamic method
dispatch, among other things, for dynamic languages.
• MacRuby
MacRuby is an implementation of the Ruby language that runs on the Objective-C
runtime and CoreFoundation framework under development by Apple Inc. which "is
supposed to replace RubyCocoa".[1] It is based on Ruby 1.9 and currently uses the
YARV bytecode interpreter, but will be based on the Low Level Virtual Machine
compiler infrastructure starting with version 0.5.
• Dylan
The Dylan programming language is a multi-paradigm language that includes support for
functional and object-oriented programming, and is dynamic and reflective while
providing a programming model designed to support efficient machine code generation,
including fine-grained control over dynamic and static behaviors. It was created in the
early 1990s by a group led by Apple Computer.
• Lisp
Lisp (or LISP) is a family of computer programming languages with a long history and a
distinctive, fully parenthesized syntax. Originally specified in 1958, Lisp is the second-
oldest high-level programming language in widespread use today; only Fortran is older.
• CLU
CLU is a programming language created at MIT by Barbara Liskov and her students
between 1974 and 1975. It was notable for its use of constructors for abstract data types
that included the code that operated on them, a key step in the direction of object-oriented
programming (OOP). However many of the other features of OOP are (intentionally)
missing, notably inheritance, and the language is also hindered by a sometimes frustrating
if elegant syntax.
• Python
38
37. Ruby On Rails
Python is a general-purpose high-level programming language.[2] Its design philosophy
emphasizes code readability.[3] Python claims to "[combine] remarkable power with very
clear syntax",[4] and its standard library is large and comprehensive. Its use of
indentation as block delimiters is unusual among popular programming languages.
• Perl
Perl is a high-level, general-purpose, interpreted, dynamic programming language. Perl
was originally developed by Larry Wall, a linguist working as a systems administrator for
NASA, in 1987, as a general purpose Unix scripting language to make report processing
easier.[1][2] Since then, it has undergone many changes and revisions and become widely
popular among programmers. Larry Wall continues to oversee development of the core
language, and its upcoming version, Perl 6.
• JRuby
JRuby is a Java implementation of the Ruby programming language, being developed by
the JRuby team. It is free software released under a three-way CPL/GPL/LGPL license.
JRuby is tightly integrated with Java to allow the embedding of the interpreter into any
Java application with full two-way access between the Java and the Ruby code
• References
38