Section 19.4. Web Development with Nitro


19.3. Ruby on Rails

One of the best known web frameworks in the Ruby realm is called Ruby on Rails (or simply Rails). This framework is the creation of David Heinemeier Hansson.

Rails makes heavy use of the dynamic features of Ruby. It also has its own design philosophy that "streamlines" web development, enabling rapid development of web-based applications.

Rails is well-known and well-documented. This book will only give it cursory coverage.

19.3.1. Principles and Techniques

Rails is built within the paradigm of the Model-View-Controller (MVC) design pattern. Every web application built with Rails is partitioned naturally into models (which model the problem domain), views (which present information to the user and allow interaction), and controllers (which arbitrate between the views and the models).

Certain principles drive the behavior of Rails as a framework. One principle is less software; don't write code to tie one thing to another if those things can be tied together automatically.

Another related principle is convention over configuration. By following certain predetermined styles in coding and naming, configuration becomes less important (and we approach the ideal "zero-config" environment).

Rails is good at automating tasks that require limited intelligence. It generates code whenever it's practical, making it unnecessary for the programmer to write those pieces manually.

Web applications are often database-backed, and Rails enables smooth, seamless integration with the database. There is also a strong tendency for a web framework to have a "preferred" object-relational mapper (ORM), and Rails is no exception. The standard ORM for Rails is ActiveRecord, which we saw in Chapter 10, "I/O and Data Storage."

The databases are described in config/database.yaml, one of the few configuration files you will ever need. This file (stored of course in YAML format) names three different databasesone for development, one for testing, and one for production. These dedicated databases may seem like overkill at first, but this scheme gives Rails much of its power.

Rails will generate empty models and controllers for you. When you edit the models, you define the relationship between the database tables with methods such as has_many and belongs_to (to name just two). Because models and tables correspond, this code also defines the relationships between the models themselves. Data validation can be accomplished with methods such as validates_presence_of (to ensure that a data item isn't missing) or validates_uniqueness_of (to ensure that a data item is unique).

When you create a Rails app with a command like rails appname, you get a directory appname with this structure:

app   controllers   helpers   models   views config db doc lib log public script test vendor


The app directory is where the bulk of your own code belongs. The MVC separation is evident from this structure, of course.

The database schemas live under the db directory. The incremental migration files will also go here as they are created.

One area where Rails simplifies life is scaffolding. If you issue a command such as script/generate scaffold Product (where Product is a model), you will get "create-update-delete" functionality generated for the Products tableplural name.

It's also possible to do scaffolding without actually generating the code. Inside the Product controller, you could use the scaffold method:

class ProductController < ActiveRecord::Base   scaffold :product end


The preceding line of code achieves the same purpose without actually generating code that lives on the disk. Either way is acceptable. Scaffolding, of course, produces entry-update pages that are functional but not very pretty; in nearly every case, the scaffolding will eventually be replaced by something better. But this quick technique of interacting with the database is handy, especially during development.

In older versions of Rails, there was a greater disconnect between ActiveRecord and the database. The concept of migrations in more recent Rails releases makes the database easier to manage. The same is true for existing database tables, which formerly were problematic; now we can easily create a schema.rb file from the existing database tables (refer also to the rake tasks db:schema:load and db:schema:dump).

19.3.2. Testing and Debugging Rails Apps

Rails has a great deal of support for testing. Notice that a test directory is created with every new application. This is populated slowly as the pieces of the app come together; you can (and should) start adding tests as you create the app.

By convention in Rails, unit tests test the models, and functional tests test the controllers. This explains the unit and functional subdirectories under the test directory. (These terms are used somewhat differently outside the context of Ruby on Rails.)

An important concept in Rails testing is the fixture. A fixture is simply a "snapshot" of the initial contents of a model; in other words, it is a set of fake data used for testing. We specify all this data in the files under the test/fixtures directory. The standard format for storing the initial data is YAML.

The test/mocks directory is for storing code that acts as mock objects. A mock object (or simply mock) is essentially an "imitation" of a service or class that is not yet implemented. Think of it as a Hollywood false front, with an interface like the real thing but nothing actually working. The classic example is a credit card payment gateway; by using mocks, we can test the interaction with the gateway without involving the real gateway.

You should know about the console in Rails. Running script/console will give you an irb-like session in which your model code is accessible. You can play with ActiveRecord queries and do similar kinds of operations.

The breakpointer is even more useful. Put a call to the breakpoint method anywhere in your code, and run the script/breakpointer utility. You will find yourself in an irb session in the context of the breakpoint that you hit in your code. This naturally will allow you to examine (and change) the values of instance variables and so on before continuing.

Recent versions of Rails also have support for integration testing. This uses a kind of custom DSL to describe the flow of control of the web application at a high level. It is designed to be useful in interacting with customers who have less technical knowledge, but it is useful even when all the users are intimately knowledgeable about the application's details.

19.3.3. Core Extensions

One of the beauties of Rails is the large selection of convenience methods defined in the ActiveSupport::CoreExtensions module. These are "harmless" methods added to the core classes for use throughout the application.

Some of these are date/time related. Because times are internally stored in seconds, it's possible to use methods such as minutes and hours in a meaningful way:

elapsed = 3.days + 4.hours + 17.minutes later = Time.now + elapsed


Similarly, we can do things like:

time = 3.minutes.from_now    # Same as Time.now + 3.minutes t2 = 5.days.from_now


Time operations are particularly well represented here, in fact. Such methods as midnight, next_month, and beginning_of_week allow us to specify times accurately and concisely.

One of the best-known items in this module is the Symbol#to_proc hack. This allows us to pass in a symbol representing a method name rather than passing in a block. For example, these two statements do the same thing:

arr = array.map {|x| x.upcase } arr = array.map(&:upcase)


Besides the methods mentioned here, there are dozens of others. Some of these handle interconversions between times or other units, some handle conversion to YAML or XML, some manipulate the spelling and punctuation of strings, and so on.

19.3.4. Related Tools and Libraries

It's inevitable that external tools have started to support Rails. The TextMate editor, for example, has good Rails support (in terms of syntax highlighting, code completion, and more). It is probably the most common editor used on the OS X platform by Rails programmers.

The InstantRails project shows great promise (http://instantrails.rubyforge.org). This is a single package containing Ruby, Rails, MySQL, and Apache, all preconfigured and ready to run. The initial version works only on the Windows platforms, but ports are planned.

On the OS/X platform, the equivalent is called Locomotive. This is a "one-click" Rails enviroment that is already mature and works well.

If you're an Eclipse fan, you should know about RadRails, which is a Rails IDE built on top of Eclipse. According to its website (http://radrails.org), "Features include source control, debugging, WEBrick servers, generator wizards, syntax highlighting, data tools and much, much more." It should run on multiple platforms (wherever Eclipse itself will run).

It's also important to understand the concept of plugins in Rails. These are small self-contained pieces of code that modify the behavior of ActiveRecord or Rails; they are simple to write and simple to deploy.

A Rails plugin is installed basically by uncompressing it and dropping it into the vendor/plugins directory. An example of a plugin is the well-known Annotate models written by Dave Thomas; it simply adds comments that summarize the current schema to the top of each ActiveRecord model source file (making this functionality available via a rake task). Literally hundreds of small plugins are available; these deal with authentication, GUIDs, I18N, CSS, and many other areas of functionality.

It is impossible to cover Rails in a handful of pages; whole books have been written about Ruby on Rails. In fact, some of the earliest ones are already obsolete as of summer 2006. If you need in-depth knowledge, begin with the website (http://rubyonrails.org) where the Rails community is centered.




The Ruby Way(c) Solutions and Techniques in Ruby Programming
The Ruby Way, Second Edition: Solutions and Techniques in Ruby Programming (2nd Edition)
ISBN: 0672328844
EAN: 2147483647
Year: 2004
Pages: 269
Authors: Hal Fulton

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net