I was bouncing around the Rails API documentation yesterday, and I noticed a few rails console tricks I haven’t seen before. There’s been plenty of posts about irb and Rails before, but I’m hoping you’ll learn something new here. The following console samples were taken with Basecamp Next on Rails version 3.2.3.

Dive into your app

Running the app method in rails console gives you an integration session instance, so you can use it just like when you’re a normal integration test for Rails.

>> app.class
=> ActionDispatch::Integration::Session

Generating routes was always a hassle. What module did I need to include again? Did you remember to set the default_url_options? Stop googling and just use app:

>> app.project_path(Project.first)
=> "/projects/130349783-with-attachments"

It can make requests inside of your app as well:

>> app.get "/735644780/projects/605816632-bcx.atom" 
=> 200

>> app.response.body
=> "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<feed xml:lang=\"en-US\"  ...

Check out ActionDispatch::Integration::Session and ActionDispatch::Integration::RequestHelpers to see what else this object can help you with.

Try out a helper

Getting a console session bootstrapped with Rails’ helpers is also a pain, which helper can fix for you! You could also use it to play with building HTML tags, or any existing Rails helper that ActionView knows about.

>> helper.truncate("Testing", length: 4)
=> "T..." 

>> helper.link_to "Home", app.root_path
=> "<a href=\"/\">Home</a>"

One gotcha with helper is using instance variables inside of helper methods. Yes, I’m aware this is a Bad Idea™ with helpers in general, but I haven’t worked in a single Rails app without one. Here’s a small example of a method with one:

def title_tag(title = nil)
  if @project.present? && title.nil?
    content_tag :title, @project.name
  elsif @project.present?
    content_tag :title, "#{@project.name}: #{title}" 
  else
    content_tag :title, title
  end
end

We can use our old friend Object#instance_variable_set to violate a core principle of OOP and let us try this helper out in the console:

>> helper.title_tag "Testing!" 
=> "<title>Testing!</title>" 

>> helper.instance_variable_set :@project, Project.first
=> #<Project id: 130349783, ...

>> helper.title_tag
=> "<title>With attachments!</title>" 

>> helper.title_tag "Posts" 
=> "<title>With attachments!: Posts</title>"

Dealing with a helper that uses params is also not straightforward. However, we can trick ActionView into listening to us with a tiny hack. This is the console, after all! Let’s say we have this helper method:

def javascript_debugging_options
  if params[:javascript_debugging] == "enabled" 
    { debug: true, digest: false }
  else
    {}
  end
end

Usually ActionView needs an entire ActionDispatch::Request from the controller to figure out what parameters came in from the user. We can trick it with a little OpenStruct instead:

>> helper.controller = OpenStruct.new(params: {})
=> #<OpenStruct params={}>

>> helper.javascript_debugging_options
=> {}

>> helper.controller = OpenStruct.new(params: {javascript_debugging: "enabled"})
=> #<OpenStruct params={:javascript_debugging=>"enabled"}>

>> helper.javascript_debugging_options
=> {:debug=>true, :digest=>false}

Where does that method come from?

Hunting down the exact location of a given method isn’t always easy. Luckily, Ruby can point you in the right direction with Method#source_location:

>> Project.instance_method(:trash).source_location
=> ["/Users/qrush/37s/apps/bcx/app/models/project.rb", 90]

Whoa! You’ll get back an array with the full path of where the method was defined along with that method’s line number in the file.

I’ve used this when looking for code buried inside of gems as well. Let’s try it on app:

>> app.method(:get).source_location
=> ["/Users/qrush/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/bundler/gems/rails-7d95b814583b/actionpack/lib/action_dispatch/testing/integration.rb", 32]

This tip has saved me from an immense amount of source diving. Try it out!

More tips

Looking for more tips? JEG2 gave a neat talk at RailsConf about some of the hidden parts of Rails you might not know about. If you have some of your own, please share!