In this article I am going to describe several ways you can debug your Rails application with ruby-debug starting from simplest and proceeding with more sophisticated setup.
Simplest of all
The simplest and most obvious way is to start your application with rdebug script:
$ rdebug ./script/server webrick
This method doesn't work with lighttpd since the latter starts several child Rails processes.
When you execute this command you end up with debugger prompt where you can set up your breakpoints.
Debugging without rdebug script
First you need to activate the debugger in your development.rb file:
./config/environments/development.rb:
...
require 'ruby-debug'
Debugger.start
Now you can use Kernel#debugger method to activate debugger:
def my_action
debugger
...
end
Remote debugging.
If for some reason you want to connect remotely to debugger, you can start it with remote debugging enabled:
$ rdebug -s ./script/server webrick
and then connect to it with
$ rdebug -c
Connected.
/usr/local/lib/ruby/1.8/webrick/server.rb:91: if svrs = IO.select(@listeners, nil, nil, 2.0)
(rdb:1)
Once again, at this point you can add breakpoints and proceed.
Adding breakpoints directly in your code
What if you don't want to setup breakpoints all the time from the debugger's command prompt and you want to use Kernel#debugger method instead. In this case when you start a debugger, you should notify it not stop when a remote client is connected with -n option:
$ rdebug -sn ./script/server webrick
Remote debugging without rdebug script
As always activate your debugger in development.rb file:
./config/environments/development.rb:
...
require 'ruby-debug'
Debugger.start_remote
Here you can control it with two options:
./config/environments/development.rb:
...
require 'ruby-debug'
Debugger.wait_connection = true
Debugger.stop_on_connect = true
Debugger.start_remote
The method I use most of the time
All described so far methods suffer from one thing: the debugger is always activated. It can slow down your application significantly. What if I want to activate it only in a particular place in my code? As always there are two ways to do that. But first you should only require debugger in development.rb file without starting it:
./config/environments/development.rb:
...
require 'ruby-debug'
Debugger#start takes a block:
def my_action
...
# at this point the debugger is still disabled
Debugger.start do
# here debugger is enabled
# below goes the code you want to debug
...
end
# at this point the debugger is disabled
...
end
Use Module#debug_method (available since version 0.4.2):
class MyController < ApplicationController
def my_action
...
end
debug_method :my_action
end
Now whenever you reach my_action method, the debugger is activated.