At the Forge - Debugging Rails Applications

 in
If and when you get stuck working on a Rails application, some of these techniques will help you identify and solve the problem more quickly than before.
Use the Console

I have been using logfiles to assist me in debugging and development for years, starting long before I began to use Rails. But logfiles allow you to see only what has happened in the past, passively. One of the best tools in a Rails developer's toolbox is the console, an interactive command-line interface that allows you to query, execute and test commands and variable values. If you are familiar with Ruby's “irb” for interactive work, the console will be familiar to you.

The console often is the first place that I write any code. It puts you in a context similar to that of a controller, allowing you to talk to the database via ActiveRecord, creating (and modifying and destroying) objects and assigning them.

For example, I often play around with associations and named scopes within the console, testing that I easily can retrieve one object through another or retrieve a subset of objects using a method call. For example, if I have a Person object and a Vehicle object, I should be able to say Person.new.vehicles in the console and get the empty array. Or, I should be able to use a named scope to say Person.men, retrieving only the men from the database.

I also use the console a great deal to test objects for validity. The valid? method for ActiveRecord objects, coupled with the save! method that raises an exception when a save goes wrong, allows me to test objects to see whether ActiveRecord believes they're valid, and why. For example, if I say:

Person.new.save!

I should get a list (not formatted beautifully, I admit) of the validations that have failed—generally indicating which attributes need to be set in order to save the person successfully. True, you always could invoke the errors method on an object after a failed save, but I find this to be faster and more obvious, which is precisely why I'm in the console.

I often use the console to piece together the methods I am going to use or just to experiment with code that eventually will go into a class or module. If you modify a model definition while you're in the console, you need to reload models with:

reload!

so that the console will be synchronized with the current state of the source code.

By default, the console operates in the development environment, so that when you write:

./script/console

you are talking to the development database.

I should note that there are a number of Ruby gems designed to improve the irb experience. One of these is wirble, which colorizes and otherwise improves the irb interface. I have been using it for a while and find it hard to use irb without its various improvements.

A newer entry is looksee, which provides a new lp (lookup path) method that shows each of the methods an object responds to, categorized and sorted as a list of ancestors. Using lp has made it easier for me to know just which class or module definition I need to inspect to investigate a particular method.

If you want to use the console for a production environment, which I often do when debugging problems on a production server, you will need to state the name of the environment explicitly:

./script/console production

I should add that recent versions of Rails include a similar command, dbconsole, which allows you to talk directly to the relational database for the environment to which you're connected. I often use dbconsole instead of typing mysql or psql (depending on the system I'm using). However, it's important to remember that when you work in the Rails console, the objects are subject to validations and other integrity checks that are not present in your raw connection to the relational database. So for safety's sake, it's usually a good idea to do things through Ruby, rather than the database. (Although if your database supports transactions, you can get some element of safety by doing all modifications within a BEGIN-COMMIT block.)

Debugger

The console, of course, is good for testing code, but you cannot run your entire Rails application inside the console. There are times, however, when you wish you could drop into the console just for a portion of your Rails application to poke around inside it. True, you could use logging statements to write the current state of affairs to the logfile, but there's nothing like interactively exploring an application from the inside to give you a better feeling about how it is working (or not).

The solution to this problem is the deceptively simple ruby-debug gem, which you can install (like all Ruby gems) by saying:

sudo gem install ruby-debug

You then need to include the gem. This typically is done in the development and/or test environment, but not in the production environment, for obvious reasons. Inside of config/environments/development.rb (or test.rb), you add:

require 'ruby-debug'

______________________

White Paper
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.

Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.

Learn More

Sponsored by ActiveState