A few more things in the Rails console

Posted by Jason King 10 months ago

Almost immediately after posting my last post on the Rails console a few more things came to mind. It has taken me this long to blog again :)

Let’s pick up from where we left off in the previous post with…

Thing 6: reload!

I can’t believe I forgot this one in the first post, this is one of the most useful methods in the console. The reload! method reloads your Rails application, so after you make change to your app you just run reload! to pick up your new changes. No more restarting your console and losing all your history. Simple, but really effective.

Thing 7: the –debugger option

Prerequisite for this to work, as with all ruby debugging, is to have the ruby-debug gem installed, so before we begin:

$ sudo gem install ruby-debug

Then, when you start your console with the --debugger option (which you can shorten to -d) you get your Rails console run under the debugger:

$ console -d
=> Debugger enabled
Loading development environment (Rails 2.3.2)
>>

So, what does this mean? Well, now you have the debugger available, so let’s make a very simple model:

app/models/foo.rb

class Foo < ActiveRecord::Base
  def foo(foo)
    puts foo.upcase
  end
end

So now in our console we want to stick a breakpoint into that model, we can either edit the app/models/foo.rb file and put in a call to the debugger method, or more simply we can just call the debugger method in the console and put in the breakpoint there:

>> debugger
/opt/local/lib/ruby/1.8/irb/context.rb:163
@last_value = value
(rdb:1) b Foo#foo
Breakpoint 1 at Foo::foo
(rdb:1) c
=> 1
>>

Only weird thing here to note is that when we call debugger we actually cause rdebug to break in the middle of the irb code. This also happens, as you’ll see below, as we step through code - when we come out of our own code, we end up debugging the console/irb code itself. Just something to be aware of and not get freaked out at.

So, now that we have that breakpoint set, let’s run some code:

>> Foo.new.foo('bar')
Breakpoint 1 at Foo:foo
.../app/models/foo.rb:2
def foo(foo)
(rdb:1) l
[-3, 6] in .../app/models/foo.rb
   1  class Foo < ActiveRecord::Base
=> 2    def foo(foo)
   3      puts foo.upcase
   4    end
   5  end
(rdb:1) n
.../app/models/foo.rb:3
puts foo.upcase
(rdb:1) pp foo
"bar"
(rdb:1) n
BAR
/opt/local/lib/ruby/1.8/irb/context.rb:163
@last_value = value
(rdb:1) c
=> nil
>>

So, here we instantiate a Foo object and send the foo method to it with the "bar" argument. You can see that our breakpoint is hit and we’re prompted with the (rdb:1) prompt. I issue the l command (short for list) to see where I am in the code, and then the n (short for next) to step over the next statement. I’m able to pp the foo parameter to see its value, and then I n again and we see the output of that puts call.

Then, as I mentioned previously, we exit our own code, but the debugger doesn’t exit. As you can see we end up on line 163 of irb/context.rb - you’ll get used to seeing this, it means that we’re back out of our code. So I just enter the c command (short for continue) and the code continues to run and returns me back to my console prompt.

Ok, fairly simple. That breakpoint will stay in the debugger until we explicitly delete it (or restart our console session). On to the next thing…

Thing 8: helper method

There are plenty of times when you’re seeing something unexpected in your browser and want to use your console to work out what’s going on. Sometimes you want to take a look at the output of a view helper, because something’s just not fitting.

Enter the helper method. This is built-in to your console session. You won’t be able to call any helper that needs to make a URL like form_for, but you still have a lot available to you. As a simple, and trivial example:

>> helper.number_to_currency( 45.234445 )
=> "$45.23"

You can get a little fancier by setting instance variables in the helper instance, like so (I’ve added a name field to my Foo model/table):

>> helper.instance_variable_set( :@foo, Foo.new( :name => 'foo bar' ) )
=> #<Foo id: nil, name: "foo bar", created_at: nil, updated_at: nil>
>> helper.text_field :foo, :name
=> "<input id=\"foo_name\" name=\"foo[name]\" size=\"30\" type=\"text\" value=\"foo bar\" />"
>> puts _
<input id="foo_name" name="foo[name]" size="30" type="text" value="foo bar" />
=> nil
>>

Very nice, yes, I like :) Next thing…

Thing 9: readline support ^R

On systems that have readline the console session will have readline support rolled in. There are many things which this brings you, emacs editing of your lines, configuration through your ~/.inputrc file, all the juicy goodness. One thing which is generally always available in all readline distributions is the ^R mapping to the readline macro history-search-backward which means that you can hit ^R (Control+R) and start typing any part of a previous (within that console session) line and readline will search backwards through your history and present you with the options.

It’s hard to demonstrate this without being live, so really - just try this yourself. Run some commands, and then hit Ctrl+R and start typing part of one of those previous commands, you’ll see what readline magic is :)

Thing 10: adjust your $PATH

Finally, a really tiny one. Not sure how this applies to Windows because I’m not sure what Windows has in its RAILS_ROOT/script directory.

You see, time and again, people doing this:

$ ruby script/console

And in fact, the same for generators and other scripts:

$ ruby script/generator model Foo name:string

Unless you have a very broken Ruby or Rails installation, then on any shebang system you can drop the ruby - everything in your script/directory will be executable, and so it can be run directly. But then, for the truly lazy (like me) why not go one step further and add ./script to your PATH so that when you’re in your RAILS_ROOT directory you can just type the command directly.

$ echo 'export PATH=./script:$PATH' >> ~/.bashrc
$ source ~/.bashrc

So, now you are all set to run those script/* scripts directly:

$ console -d
...
$ generate model Foo name:string
...

Etc..


I hope those make your life a lot simpler. I’ll settle for just a little simpler. Have fun.

Comments

There are 0 comments on this post. Post yours →

Post a comment

Required fields look like this.

Markdown enabled. See the syntax rules for help.