My friend the Rails console – Part II
You can find the first part clicking here.
Despite all this Rails 3 thingy, we have to face it, we won't ditch Rails 2.3.x anytime soon, so I'm still in the mood to post things about Rails 2.3.x. This time I'll try to provide you guys with some Rails 3 version of the tricks or tips shown here.
Let's get it started.
Accessing helpers
When we fire up the Rails console automatically we have an instance of ActionView::Base called helper; if you have helper :all in your ApplicationController all the files in the app/helpers folder will be available in the helper object.
If we included all the helpers, using the Double-TAB trick (completion) would be a little bit annoying because we might have a lot of helpers starting with the same words. Let's fix it.
waza = ActionView::Base.new waza.extend WazaHelper waza.waza_helper_method(10) # => <waza>10</waza>
Remember that all the helpers are Ruby modules, and we can't instance modules, only mix them into classes
Now, let's say we haven't included all the helpers and we need to use one of those, say WazaHelper again.
helper.waza_helper_method # => method not found include WazaHelper waza.waza_helper_method(10) # => <waza>10</waza>
ActionController logging
In the first part of this post I spoke about calling controller actions from console, well, now I want to see what is being logged when I call those actions:
ActionController::Base.logger = Logger.new(STDOUT) reload!
Or you can use a helper from my .irbrc:
log_ac_to STDOUT
Log your sessions to a separate log file
Let's say you have a buggy model and you are in one of those never-ending debugging sessions, and you'd like to send all the ActiveRecord logs to a separate file:
my_logger = Logger.new('log/my_logger.log')
my_logger.info('testing my logger') # go to see my_logger.log
ActiveRecord::Base.logger = my_logger
reload!
NOTE: Logger.new will create the log/my_logger.log if it doesn't exists, if it does, it'll use it.
Now, If you want to send the logs back to the console
ActiveRecord::Base.logger = Logger.new(STDOUT) reload!
Or you can use a helper from my .irbrc:
log_ar_to :waza #ActiveRecord will log to log/waza.log log_ar_to STDOUT #ActiveRecord will log to console
Environment shortcuts in Rails 2
There are several ways to specify the environment:
$ RAILS_ENV=production script/console $ script/console production
but there are a shorter way to do it:
$ alias sc='script/console' # you can put this in your ~/.bash_profile or ~/.bashrc $ sc p # => production $ sc d # => development $ sc t # => test
The "p", "d" and "e" shortcuts were implemented in Rails 2, you can see the implementation clicking here
Sadly, this won't work in Rails 3, these shortcuts have been deprecated and I haven't found either any documentation about the shortcuts nor any deprecation warning in Rails 3.
The good news is that Rails 3 comes with some predefined shortcuts by default
$ rails --help #it will show the list of commands and their shortcuts console Start the Rails console (short-cut alias: "c") server Start the Rails server (short-cut alias: "s")
Let's make it even shorter
$ alias r='rails' # you can put this in your ~/.bash_profile or ~/.bashrc $ r c
Using different ruby versions in the console
$ script/console --irb ruby1.9
In Rails 3 the --irb option has been deprecated, if you use this option Rails 3 will respond with:
DEPRECATED: Invoke `/your/choice/of/ruby script/rails console` instead
so you have to do:
$ ruby1.9 script/rails console
The Rails Runner
Suppose you want to run some specific code in the Rails context, you can use script/console but sometimes you want to execute just a single line, that's what the runner was made for:
$ alias sr='script/runner' $ sr 'MyJob.new.do_it'
You can send a file as argument too and specify an environment
$ sr -e production 'deploy.rb'
Want to send arguments to the deploy.rb file?
$ sr -e production 'deploy.rb' -- arg1 arg2
If you want to schedule a background job to run every 15 minutes:
0,15,30,45 * * * * PATH_TO_APP/script/runner -e production 'MyJob.new.perform'
The ~/.irbrc file
Everytime you fire the rails console or even just irb, this file is read. You can load gems, insert helpers, extend the ruby core, etc.
You can find my personal .irbrc file in this git repository http://github.com/rafmagana/irbrc
Hacking IRb
There's a number of gems that will help to make the console even better:
Utility Belt - http://utilitybelt.rubyforge.org/
Wirble - http://pablotron.org/software/wirble/
Pretty Print - http://is.gd/dAg40
Awesome Print - http://github.com/michaeldv/awesome_print
But, what if you don't find what you need in any library.? My first approach is to look for others .irbrc's and copy what I find useful, if I don't find what I need I make my own helpers.
Here I'll show you some simple examples.
Helpers
Sometimes I find myself writing 'clear' but that method doesn't exist in IRb, so
def clear
system('clear')
end
The following is a very common trick among ruby developers
class Object
def local_methods
(methods - Object.instance_methods).sort
end
end
it returns an array of methods defined in the parent class of the object
class Waza
def say_hello(name)
"hello, #{name}"
end
end
w = Waza.new
w.local_methods # => ["say_hello"]
Nice!, let's get a little bit further
class Class
def class_methods
(methods - Class.instance_methods - Object.methods).sort
end
end
class Waza
def self.am_i_a_class?
"yes, and an object too"
end
end
Waza.class_methods # => ["am_i_a_class?"]
Interacting with the Mac pasteboard (clipboard)
Mac OS has some commands to access the pasteboard from terminal (http://is.gd/dAQjQ), pbcopy and pbpaste:
$ echo "http://download/file.zip" | pbcopy (or you can press Cmd-C in Safari or wherever) $ wget `pbpaste` # wget http://download/file.zip (Cmd-V)
I really use these commands almost as a daily basis, but I wanted to use them in IRb, so I did it.
In my .irbrc you can find I extended the Object class with two methods:
Object#to_pb => copy text to the Mac OS's pasteboard
Object#paste => paste text from the Mac OS's pasteboard
UPDATE: I made a gem called PasterboaRb that adds these methods to the Object class.
"my text".to_pb
If you go to any Mac application and press Cmd-V the "my text" text will be pasted.
"ruby".to_pb waza.say_hello paste # => "hello, ruby"
The Mac OS has 4 pasteboards: general, ruler, find and font.
"mac".to_pb :general # default "rails".to_pb :find "ruby".to_pb :ruler "rack".to_pb :font waza.say_hello(paste :find) # => "hello, rails" waza.say_hello(paste :ruler) # => "hello, ruby" waza.say_hello(paste :general) # => "hello, mac" waza.say_hello(paste :font) # => "hello, rack"
I really don't know what "ruler" and "font" are useful for, I couldn't find any documentation, but:
"general" - it's the default pasteboard; Cmd-C and Cmd-V use this pasteboard
"find" - Used by Cocoa applications to hold the value of the find field. (Whaaaat?)
Do the following:
"find rails".to_pb :find
Then open Safari or Textmate or whatever Cocoa application you want, now press Cmd-F and the text field will be automatically populated with the value of the "find" pasteboard, in this case, "find rails".
Real-life examples?
If I need to share an objects through several IRb sessions, I mean, in different terminals.
Terminal 1
w = Waza.new w.name = "rails" w.to_yaml.to_pb
Terminal 2
w = YAML::load paste w.name # => "rails"
Sometimes I want to copy to the pasteboard something that a method returns, like usernames, email addresses, passwords, etc:
User.find(10).email.to_pb
Then I can paste the email pressing Cmd-V wherever I want. Yes, I'm that lazy.
That's it, hope it helps.
August 14th, 2010 - 15:05
Here is an additional helper I find very useful with an example of what is output: http://gist.github.com/524652
August 14th, 2010 - 16:10
woooooow, really impressive! I’d do this instead:
class Object
def pm(*options)
…
#instead of “obj” it should say “self”
…
end
end
$ Time.pm
it’d be more object-oriented. Thanks for sharing!!!!
September 14th, 2010 - 15:17
Thank you for the pointer. Makes sense to self. ROCK!
January 22nd, 2012 - 14:50
Holy cocinse data batman. Lol!
August 14th, 2010 - 00:57
Seeing the number of helpers/commands you have, you may be interested in boson: http://github.com/cldwalker/boson. I use it to manage my irbrc: http://github.com/cldwalker/irbfiles
July 21st, 2010 - 12:52
Awesome tips, Raf! Keep them coming