- •Contents
- •Preface to the Second Edition
- •Introduction
- •Rails Is Agile
- •Finding Your Way Around
- •Acknowledgments
- •Getting Started
- •The Architecture of Rails Applications
- •Models, Views, and Controllers
- •Active Record: Rails Model Support
- •Action Pack: The View and Controller
- •Installing Rails
- •Your Shopping List
- •Installing on Windows
- •Installing on Mac OS X
- •Installing on Linux
- •Development Environments
- •Rails and Databases
- •Rails and ISPs
- •Creating a New Application
- •Hello, Rails!
- •Linking Pages Together
- •What We Just Did
- •Building an Application
- •The Depot Application
- •Incremental Development
- •What Depot Does
- •Task A: Product Maintenance
- •Iteration A1: Get Something Running
- •Iteration A2: Add a Missing Column
- •Iteration A3: Validate!
- •Iteration A4: Prettier Listings
- •Task B: Catalog Display
- •Iteration B1: Create the Catalog Listing
- •Iteration B4: Linking to the Cart
- •Task C: Cart Creation
- •Sessions
- •Iteration C1: Creating a Cart
- •Iteration C2: A Smarter Cart
- •Iteration C3: Handling Errors
- •Iteration C4: Finishing the Cart
- •Task D: Add a Dash of AJAX
- •Iteration D1: Moving the Cart
- •Iteration D3: Highlighting Changes
- •Iteration D4: Hide an Empty Cart
- •Iteration D5: Degrading If Javascript Is Disabled
- •What We Just Did
- •Task E: Check Out!
- •Iteration E1: Capturing an Order
- •Task F: Administration
- •Iteration F1: Adding Users
- •Iteration F2: Logging In
- •Iteration F3: Limiting Access
- •Iteration F4: A Sidebar, More Administration
- •Task G: One Last Wafer-Thin Change
- •Generating the XML Feed
- •Finishing Up
- •Task T: Testing
- •Tests Baked Right In
- •Unit Testing of Models
- •Functional Testing of Controllers
- •Integration Testing of Applications
- •Performance Testing
- •Using Mock Objects
- •The Rails Framework
- •Rails in Depth
- •Directory Structure
- •Naming Conventions
- •Logging in Rails
- •Debugging Hints
- •Active Support
- •Generally Available Extensions
- •Enumerations and Arrays
- •String Extensions
- •Extensions to Numbers
- •Time and Date Extensions
- •An Extension to Ruby Symbols
- •with_options
- •Unicode Support
- •Migrations
- •Creating and Running Migrations
- •Anatomy of a Migration
- •Managing Tables
- •Data Migrations
- •Advanced Migrations
- •When Migrations Go Bad
- •Schema Manipulation Outside Migrations
- •Managing Migrations
- •Tables and Classes
- •Columns and Attributes
- •Primary Keys and IDs
- •Connecting to the Database
- •Aggregation and Structured Data
- •Miscellany
- •Creating Foreign Keys
- •Specifying Relationships in Models
- •belongs_to and has_xxx Declarations
- •Joining to Multiple Tables
- •Acts As
- •When Things Get Saved
- •Preloading Child Rows
- •Counters
- •Validation
- •Callbacks
- •Advanced Attributes
- •Transactions
- •Action Controller: Routing and URLs
- •The Basics
- •Routing Requests
- •Action Controller and Rails
- •Action Methods
- •Cookies and Sessions
- •Caching, Part One
- •The Problem with GET Requests
- •Action View
- •Templates
- •Using Helpers
- •How Forms Work
- •Forms That Wrap Model Objects
- •Custom Form Builders
- •Working with Nonmodel Fields
- •Uploading Files to Rails Applications
- •Layouts and Components
- •Caching, Part Two
- •Adding New Templating Systems
- •Prototype
- •Script.aculo.us
- •RJS Templates
- •Conclusion
- •Action Mailer
- •Web Services on Rails
- •Dispatching Modes
- •Using Alternate Dispatching
- •Method Invocation Interception
- •Testing Web Services
- •Protocol Clients
- •Secure and Deploy Your Application
- •Securing Your Rails Application
- •SQL Injection
- •Creating Records Directly from Form Parameters
- •Avoid Session Fixation Attacks
- •File Uploads
- •Use SSL to Transmit Sensitive Information
- •Knowing That It Works
- •Deployment and Production
- •Starting Early
- •How a Production Server Works
- •Repeatable Deployments with Capistrano
- •Setting Up a Deployment Environment
- •Checking Up on a Deployed Application
- •Production Application Chores
- •Moving On to Launch and Beyond
- •Appendices
- •Introduction to Ruby
- •Classes
- •Source Code
- •Resources
- •Index
- •Symbols
RAILS AND DATABASES 39
Creating Your Own Rails API Documentation
You can create your own local version of the consolidated Rails API documentation. Just type the following commands at a command prompt (remembering to start the command window in your Rails environment if you’re using InstantRails or Locomotive).
rails_apps> rails dummy_app rails_apps> cd dummy_app dummy_app> rake rails:freeze:gems
dummy_app> echo >vendor/rails/activesupport/README dummy_app> rake doc:rails
The last step takes a while. When it finishes, you’ll have the Rails API documentation in a directory tree starting at doc/api. I suggest moving this folder to your desktop, then deleting the dummy_app tree.
The Desktop
I’m not going to tell you how to organize your desktop while working with Rails, but I will describe what I do.
Most of the time, I’m writing code, running tests, and poking at my application in a browser. So my main development desktop has an editor window and a browser window permanently open. I also want to keep an eye on the logging that’s generated by my application, so I keep a terminal window open. In it I use tail -f to scroll the contents of the log file as it’s updated. I normally run this window with a very small font so it takes up less space—if I see something interesting flash by, I zoom it up to investigate.
I also need access to the Rails API documentation, which I view in a browser. In the introduction we talked about using the gem_server command to run a local web server containing the Rails documentation. This is convenient, but it unfortunately splits the Rails documentation across a number of separate documentation trees. If you’re online, you can use http://api.rubyonrails.org to see a consolidated view of all the Rails documentation in one place. The sidebar describes how to create this same documentation on your own machine.
3.6Rails and Databases
The examples in this book were written using MySQL (version 5.0.22 or thereabouts). If you want to follow along with our code, it’s probably simplest if you use MySQL too. If you decide to use something else, it won’t be a major problem. You may have to make minor adjustments to any explicit SQL in our code, but Rails pretty much eliminates database-specific SQL from applications.
Report erratum
RAILS AND DATABASES 40
Database Passwords
Here’s a note that may well prove to be controversial. You always want to set a password on your production database. However, most Rails developers don’t seem to bother doing it on their development databases. In fact, most go even further down the lazy road and just use the default MySQL root user when in development too. Is this dangerous? Some folks say so, but the average development machine is (or should be) behind a firewall. And, with MySQL, you can go a step further and disable remote access to the database by setting the skip-networking option. So, in this book, we’ll assume you’ve gone with the flow. If instead you’ve created special database users and/or set passwords, you’ll need to adjust your connection parameters and the commands you type (for example adding the -p option to MySQL commands if you have a password set). For some online notes on creating secure MySQL installations for production, have a look at an article at Security Focus (http://www.securityfocus.com/infocus/1726).
You need two layers of software to link your application code to the database engine. The first is the database driver, a Ruby library that connects the lowlevel database API to the higher-level world of Ruby programming. Because databases are normally supplied with interface libraries accessible from C, these Ruby libraries are typically written in C and have to be compiled for your target environment.7 The second layer of code is the Rails database adapter. This sits between the Ruby library and your application. Each database library will have its own database-specific API. The Rails database adapters hide these differences so that a Rails application doesn’t need to know what kind of database it is running on.
We installed the MySQL database driver in the installation steps at the start of this chapter. This is probably good enough while you’re getting to know Rails. If so, you can safely skip to Section 3.7, Keeping Up-to-Date, on page 42.
If you’re still reading this, it means you want to connect to a database other than MySQL. Rails works with DB2, MySQL, Oracle, Postgres, Firebird, SQL Server, and SQLite. For all but MySQL, you’ll need to install a database driver, a library that Rails can use to connect to and use your database engine. This section contains the links and instructions to get that done.
The database drivers are all written in C and are primarily distributed in source form. If you don’t want to bother building a driver from source, have a careful look on the driver’s web site. Many times you’ll find that the author also distributes binary versions.
7. However, you may not have to do the compiling yourself—it’s often possible to find precompiled libraries for your platform.
Report erratum
RAILS AND DATABASES 41
If you can’t find a binary version or if you’d rather build from source anyway, you’ll need a development environment on your machine to build the library. Under Windows, this means having a copy of Visual C++. Under Linux, you’ll need gcc and friends (but these will likely already be installed).
Under OS X, you’ll need to install the developer tools (they come with the operating system but aren’t installed by default). You’ll also need to install your database driver into the correct version of Ruby. In the installation instructions starting back on page 34 we installed our own copy of Ruby, bypassing the built-in one. It’s important to remember to have this version of Ruby first in your path when building and installing the database driver. I always run the command which ruby to make sure I’m not running Ruby from /usr/bin.
The following table lists the available database adapters and gives links to their respective home pages.
DB2 |
http://raa.ruby-lang.org/project/ruby-db2 |
Firebird |
http://rubyforge.org/projects/fireruby/ |
MySQL |
http://www.tmtm.org/en/mysql/ruby |
Oracle |
http://rubyforge.org/projects/ruby-oci8 |
Postgres |
http://ruby.scripting.ca/postgres/ |
SQL Server |
(see notes after table) |
SQLite |
http://rubyforge.org/projects/sqlite-ruby |
There is a pure-Ruby version of the Postgres adapter available. Download postgres-pr from the Ruby-DBI page at http://rubyforge.org/projects/ruby-dbi.
MySQL and SQLite are also available for download as RubyGems (mysql and sqlite, respectively).
Interfacing to SQL Server requires a little effort. The following is based on a note written by Joey Gibson, who wrote the Rails adapter.
Assuming you used the one-click installer to load Ruby onto your system, you already have most of the libraries you need to connect to SQL Server. However, the ADO module is not installed. Follow these steps (courtesy of Daniel Berger):
1.Wander over to http://rubyforge.org/projects/ruby-dbi, and get the latest distribution of Ruby-DBI.
2.Open a command window, and navigate to where you unpacked the rubydbi library. Enter these commands:
c:\ruby-dbi> ruby setup.rb config --with=dbd_ado c:\ruby-dbi> ruby setup.rb setup
c:\ruby-dbi> ruby setup.rb install
The SQL Server adapter will work only on Windows systems, because it relies on Win32OLE.
Report erratum
KEEPING UP-TO-DATE 42
3.7Keeping Up-to-Date
Assuming you installed Rails using RubyGems, keeping up-to-date is relatively easy. Issue the command
dave> gem update rails --include-dependencies
and RubyGems will automatically update your Rails installation. The next time you start your application, it will pick up this latest version of Rails. (We have more to say about updating your application in production in the Deployment and Scaling chapter, starting on page 613.) RubyGems keeps previous versions of the libraries it installs. You can delete these with the command
dave> gem cleanup
After installing a new version of Rails, you might also want to update the files that Rails initially added to your applications (the JavaScript libraries it uses for AJAX support, various scripts, and so on). You can do this by running the following command in your application’s top-level directory.
app> rake rails:update
3.8Rails and ISPs
If you’re looking to put a Rails application online in a shared hosting environment, you’ll need to find a Ruby-savvy ISP. Look for one that supports Ruby, has the Ruby database drivers you need, and offers FastCGI and/or LightTPD support. We’ll have more to say about deploying Rails applications in Chapter 27, Deployment and Production, on page 613.
The page http://wiki.rubyonrails.com/rails/pages/RailsWebHosts on the Rails wiki lists some Rails-friendly ISPs.
Now that we have Rails installed, let’s use it. On to the next chapter.
Report erratum