In my previous article, we looked at Pry, an extremely powerful alternative to the standard IRB shell that Ruby gives us.
For those who work with Rails, you will be happy to know that Pry has got your back. In this article, we look at the various ways Pry vastly improves our Rails workflow.
Do note that Pry works best with Ruby 1.9.3 and up.
Key Takeaways
- Pry is a powerful alternative to the standard IRB shell that Ruby provides, offering improved workflow for Rails developers. It works best with Ruby 1.9.3 and up.
- Installing Pry with Rails involves adding the pry-rails gem to the gemfile, or using Jazz Hands which includes pry-rails and other useful features like Awesome Print, Pry Doc, Pry Remote, Pry Debugger, and Pry Stack Explorer.
- Pry provides tools to explore a Rails project without opening a single file, such as show-models to display the models a project contains, and show-routes to display routes.
- Pry’s debugging capabilities are significant, allowing developers to introduce and debug errors directly from Pry. It also allows for the inspection of variables in scope and the editing of method definitions. The better_errors gem can make this process more efficient.
Getting the Sample Application
For our sample application, we would be using the application written for the Rails 3 tutorial by Michael Hartl.
To grab the application:
git clone git@github.com:benjamintanweihao/sample_app.git
Installing Pry with Rails
You could install pry
on Rails by adding the pry-rails
gem to your gemfile:
gem 'pry-rails', :group => :development
Or you could get that and other goodies with Jazz Hands.
group :development do
gem 'jazz_hands'
end
Out of the box, Jazz Hands not only includes pry-rails
, but it also includes other niceties such as:
- Awesome Print
- Pry Doc
- Pry Remote
- Pry Debugger
- Pry Stack Explorer
Once you have got that settled, change back into the sample_app
directory and install all the necessary dependencies:
bundle install
Setting up the database
rake db:schema:load
Note that some of you might need to prefix the above command with bundle exec
.
One final thing before we proceed to the fun stuff: Create .pryrc
in your home directory:
% touch ~/.pryrc
Fill it in with the editor of your choice:
Pry.config.editor = 'vim'
Launching Pry
… is trivial. Simply do a
rails c
and you’re greeted with a pry
console:
% rails c
Loading development environment (Rails 3.2.16)
Frame number: 0/3
[1] sample_app »
Exploring a Rails project
Pry gives you a few tools to poke around a project without having to open a single file.
show-models
The first thing we’ll do is see what models the project contains. This is exactly what show-models
tell you:
[1] sample_app » show-models
Micropost
id: integer
content: string
user_id: integer
created_at: datetime
updated_at: datetime
belongs_to :user
Relationship
id: integer
follower_id: integer
followed_id: integer
created_at: datetime
updated_at: datetime
belongs_to :followed
belongs_to :follower
User
id: integer
name: string
email: string
created_at: datetime
updated_at: datetime
password_digest: string
remember_token: string
admin: boolean
has_many :followed_users (through :relationships)
has_many :followers (through :reverse_relationships)
has_many :microposts
has_many :relationships
has_many :reverse_relationships
Very awesome! Notice that the output has some very pretty syntax highlighting.
show-routes
rake routes
is something I do pretty frequently. Sometimes, when I’m in the midst of a console session, it can be quite inconvenient and distracting to switch windows/tabs just to display the routes.
That is, until show-routes
came along:
[2] sample_app » show-routes
following_user GET /users/:id/following(.:format) users#following
followers_user GET /users/:id/followers(.:format) users#followers
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
sessions POST /sessions(.:format) sessions#create
new_session GET /sessions/new(.:format) sessions#new
session DELETE /sessions/:id(.:format) sessions#destroy
microposts POST /microposts(.:format) microposts#create
micropost DELETE /microposts/:id(.:format) microposts#destroy
relationships POST /relationships(.:format) relationships#create
relationship DELETE /relationships/:id(.:format) relationships#destroy
root / static_pages#home
signup /signup(.:format) users#new
signin /signin(.:format) sessions#new
signout DELETE /signout(.:format) sessions#destroy
help /help(.:format) static_pages#help
about /about(.:format) static_pages#about
contact /contact(.:format) static_pages#contact
show-routes
has another really useful feature: For larger Rails projects, simply displaying all the routes would easily flood your screen and cause your eyes to water.
Let’s find out what else show-routes
is capable of. Prefix the command with a ?
):
[3] sample_app » ? show-routes
From: /usr/local/var/rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/pry-rails-0.3.2/lib/pry-rails/commands/show_routes.rb
Number of lines: 6
Usage: show-routes [-G]
show-routes displays the current Rails app's routes.
-G, --grep Filter output by regular expression
-h, --help Show this message.
So, if I wanted to recall whether it was sign_up
or signup
, I can do a quick filter:
[3] sample_app » show-routes -G sign
signup /signup(.:format) users#new
signin /signin(.:format) sessions#new
signout DELETE /signout(.:format) sessions#destroy
To display all the POST
actions:
[4] sample_app » show-routes -G POST
POST /users(.:format) users#create
sessions POST /sessions(.:format) sessions#create
microposts POST /microposts(.:format) microposts#create
relationships POST /relationships(.:format) relationships#create
Awesome Printing is Awesome.
(Note: This is not part of pry-rails, but is installed with Jazz Hands. You can get awesome_print by installing the gem standalone, if needed.)
When you do Model.all
, the result is usually an unintelligible mess. Here’s a sample of how awesome-print
eases that pain (I went ahead and created some Micropost
records):
[5] sample_app » Micropost.all
Micropost Load (0.2ms) SELECT "microposts".* FROM "microposts" ORDER BY microposts.created_at DESC
=> [
[0] #<Micropost:0x007ff7dcda7038> {
:id => 2,
:content => "Sure is! Wait till you combine it with Rails!",
:user_id => 1,
:created_at => Mon, 27 Jan 2014 15:13:35 UTC +00:00,
:updated_at => Mon, 27 Jan 2014 15:13:35 UTC +00:00
},
[1] #<Micropost:0x007ff7dd66e770> {
:id => 1,
:content => "Hello! Isn't Pry awesome?",
:user_id => 1,
:created_at => Mon, 27 Jan 2014 15:13:21 UTC +00:00,
:updated_at => Mon, 27 Jan 2014 15:13:21 UTC +00:00
}
]
Once you are used to this beautifully formatted, color-coded output, you will never turn back to the plain old rails console
ever again.
show-doc
Do not forget that the entire documentation is within easy reach:
[6] sample_app » cd Array
[7] sample_app(../Array) » show-doc each_cons
From: enum.c (C Method):
Owner: Enumerable
Visibility: public
Signature: each_cons(arg1)
Number of lines: 14
Iterates the given block for each array of consecutive <n>
elements. If no block is given, returns an enumerator.
e.g.:
(1..10).each_cons(3) { |a| p a }
# outputs below
[1, 2, 3]
[2, 3, 4]
[3, 4, 5]
[4, 5, 6]
[5, 6, 7]
[6, 7, 8]
[7, 8, 9]
[8, 9, 10]
Debugging
Pry really shines is its debugging capabilities. Let’s purposely introduce a bug into our project directly from Pry.
First, navigate to the UsersController
:
[8] sample_app » cd UsersController
[9] sample_app(../UsersController) »
show-source
Recall that we can inspect the file source with the show-source
command:
[10] sample_app(../UsersController) » show-source
From: /Users/rambo/Desktop/sample_app/app/controllers/users_controller.rb @ line 1:
Class name: UsersController
Number of monkeypatches: 4. Use the `-a` option to display all available monkeypatches
Number of lines: 74
class UsersController < ApplicationController
before_filter :signed_in_user,
only: [:index, :edit, :update, :destroy, :following, :followers]
before_filter :correct_user, only: [:edit, :update]
before_filter :admin_user, only: :destroy
def index
@users = User.paginate(page: params[:page])
end
def show
@user = User.find(params[:id])
@microposts = @user.microposts.paginate(page: params[:page])
end
# Other code omitted ...
end
edit-method
Now, let’s introduce the bug in the index
action:
[10] sample_app(../UsersController) » edit index
Notice that vim (or whatever editor you configured previously) shows up, with the cursor directly at the start of the method definition.
Now, just add a raise
at the bottom of the index
action:
def index
@users = User.paginate(page: params[:page])
raise # <-- Add this
end
After you save and exit, you will be returned to the console.
Debugging with binding.pry
Obviously, when you navigate to http://localhost:3000/users
, it will blow up.
Let’s assume you encounter some error in your app. Here are the steps which I usually take:
cd
into the classedit
the offending method- add
binding.pry
So let’s go back into our console, and do just that:
def index
@users = User.paginate(page: params[:page])
binding.pry
raise
end
This time, navigate to http://localhost:3000/users
. However, instead of blowing up, notice that the browser just hangs there.
Check your console window where your launched the rails server. You will notice that there’s another Pry session all prepared for you:
Frame number: 0/66
From: /Users/rambo/Desktop/sample_app/app/controllers/users_controller.rb @ line 9 UsersController#index:
7: def index
8: @users = User.paginate(page: params[:page])
=> 9: binding.pry
10: raise
11: end
[1] sample_app(#<UsersController>) »
In this session, you can easily examine all the variables that are in the scope.
We can inspect the contents of @users
:
[3] sample_app(#<UsersController>) » @users
=> [
[0] #<User:0x007f847f108168> {
:id => 1,
:name => "Benjamin Tan Wei Hao",
:created_at => Mon, 27 Jan 2014 14:18:22 UTC +00:00,
:updated_at => Mon, 27 Jan 2014 14:18:22 UTC +00:00,
:admin => false
}
]
Let’s try params
:
[2] sample_app(#<UsersController>) » params
=> {
"action" => "index",
"controller" => "users"
}
session
works too:
[4] sample_app(#<UsersController>) » session
=> {
"session_id" => "812d9cfb949e795ed2fef78c2188fc0e",
"_csrf_token" => "e+MnQKg2URyBEhkXdxpwcmJnyeRT5J+Tc1PGMvYpoU4="
}
Once done, you can go ahead and use edit method_name
to remove binding.pry
and the raise
.
Also, remember to exit
, otherwise the request would be blocked indefinitely.
Better Errors
Sometimes, you need binding.pry
to poke around variables and trace methods. It is also a good way to impress your programmer friends/colleagues.
But when you are done with that, you would soon realise that it slowly becomes a hassle. Thankfully, there’s the better_errors
gem that does away with all the ceremony.
Installation
group :development do
gem "better_errors"
gem "binding_of_caller"
end
As the README notes, do not place this under the production
group.
I included the raise
error again in UsersController#index
. If you take a look at the browser, the usual Rails error page is replaced with something much, much, MUCH better:
Wrapping Up
Hopefully I have convinced you, once again, of the awesomeness of Pry. Maybe you’re even inspired to use some of the techniques here to improve your Rails workflow.
Happy Prying!
Frequently Asked Questions (FAQs) about Pry in Rails
How do I install Pry in Rails?
Installing Pry in Rails is a straightforward process. First, you need to add the gem to your Gemfile. You can do this by opening your Gemfile in a text editor and adding the following line: gem 'pry-rails'
. After adding the line, save and close the file. Then, run bundle install
in your terminal to install the gem. Once the installation is complete, you can use Pry in your Rails application.
What are the benefits of using Pry over IRB in Rails?
Pry offers several advantages over the default IRB console in Rails. It provides syntax highlighting, which makes it easier to read and understand the code. It also allows you to navigate through your code with shell-like cd and ls commands, making it more convenient to use. Additionally, Pry provides powerful introspection capabilities, allowing you to dive deep into your code and understand how it works.
How can I use Pry for debugging in Rails?
Pry can be a powerful tool for debugging in Rails. You can insert binding.pry
into your code at the point where you want to pause execution. When your application reaches this point, it will open a Pry session in your terminal, allowing you to inspect variables, call methods, and step through your code.
Can I use Pry with Rails testing frameworks?
Yes, you can use Pry with Rails testing frameworks like RSpec and MiniTest. To do this, you need to require the Pry gem in your test helper file and insert binding.pry
into your tests where you want to pause execution. This will allow you to inspect your test environment and debug your tests.
How can I customize Pry’s behavior in Rails?
Pry’s behavior can be customized by creating a .pryrc
file in your home directory. In this file, you can define custom commands, set default options, and configure Pry’s appearance. For example, you can change the prompt, enable or disable certain plugins, and set default options for commands.
Can I use Pry to inspect Rails models and controllers?
Yes, you can use Pry to inspect Rails models and controllers. By inserting binding.pry
into your models or controllers, you can pause execution and inspect the state of your application at that point. This can be particularly useful for understanding complex queries or debugging issues with your controllers.
How can I use Pry to step through code in Rails?
To step through code with Pry, you need to use the step
command. When you hit a binding.pry
in your code, you can type step
into the Pry console to move to the next line of code. You can also use next
to move to the next line without stepping into methods, and continue
to resume execution until the next binding.pry
.
Can I use Pry to edit code in Rails?
Yes, you can use Pry to edit code in Rails. The edit
command allows you to open the current file in your text editor, make changes, and then continue execution with the updated code. This can be a powerful tool for debugging and development.
How can I use Pry to inspect Rails routes?
You can use Pry to inspect Rails routes by running rails routes
in a Pry session. This will display a list of all your application’s routes, along with the corresponding controller actions. You can also use show-route
to display information about a specific route.
Can I use Pry in production environments?
While it’s technically possible to use Pry in production environments, it’s generally not recommended. Using Pry in production can expose sensitive information and potentially disrupt your application. It’s best to use Pry in development and test environments, where it can help you debug and understand your code without risking your production data.
Benjamin is a Software Engineer at EasyMile, Singapore where he spends most of his time wrangling data pipelines and automating all the things. He is the author of The Little Elixir and OTP Guidebook and Mastering Ruby Closures Book. Deathly afraid of being irrelevant, is always trying to catch up on his ever-growing reading list. He blogs, codes and tweets.