Rails Console Debugging Tricks
This article will demonstrate a few Rails console tricks that you may not be aware of.
Published on:August 11, 2016
Introduction
As many of you may know, Rails provides a handy console
command that can be used to execute code within the context of your application. Simply running rails c
at a terminal will start this rails console session. What you may not know is that there are several useful debugging tricks you can utilize in order to debug and test your application. This article will cover a few of those tricks. Let's get started.
Rails Console Tricks
You can view object details in YAML format. Simply use the y
function:
2.3.1 :002 > article = Article.find(1)
Article Load (0.3ms) SELECT "articles".* FROM "articles" WHERE "articles"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
=> #<Article id: 1, title: "Test Article", body: "Test Article Body", created_at: "2016-08-04 02:11:06", updated_at: "2016-08-04 02:11:06">
2.3.1 :003 > y article
--- !ruby/object:Article
raw_attributes:
id: 1
title: Test Article
body: Test Article Body
created_at: '2016-08-04 02:11:06.557227'
updated_at: '2016-08-04 02:11:06.557227'
attributes: !ruby/object:ActiveRecord::AttributeSet
attributes: !ruby/object:ActiveRecord::LazyAttributeHash
types:
id: &2 !ruby/object:ActiveModel::Type::Integer
precision:
scale:
limit:
range: !ruby/range
begin: -2147483648
end: 2147483648
excl: true
title: &3 !ruby/object:ActiveModel::Type::String
precision:
scale:
limit:
body: &4 !ruby/object:ActiveModel::Type::Text
precision:
scale:
limit:
created_at: &5 !ruby/marshalable:ActiveRecord::AttributeMethods::TimeZoneConversion::TimeZoneConverter
:__v2__: []
[]: &1 !ruby/object:ActiveRecord::Type::DateTime
precision:
scale:
limit:
updated_at: &7 !ruby/marshalable:ActiveRecord::AttributeMethods::TimeZoneConversion::TimeZoneConverter
:__v2__: []
[]: *1
values:
id: 1
title: Test Article
body: Test Article Body
created_at: '2016-08-04 02:11:06.557227'
updated_at: '2016-08-04 02:11:06.557227'
additional_types: {}
materialized: true
delegate_hash:
id: !ruby/object:ActiveRecord::Attribute::FromDatabase
name: id
value_before_type_cast: 1
type: *2
original_attribute:
value: 1
title: !ruby/object:ActiveRecord::Attribute::FromDatabase
name: title
value_before_type_cast: Test Article
type: *3
original_attribute:
value: Test Article
body: !ruby/object:ActiveRecord::Attribute::FromDatabase
name: body
value_before_type_cast: Test Article Body
type: *4
original_attribute:
value: Test Article Body
created_at: !ruby/object:ActiveRecord::Attribute::FromDatabase
name: created_at
value_before_type_cast: '2016-08-04 02:11:06.557227'
type: *5
original_attribute:
value: !ruby/object:ActiveSupport::TimeWithZone
utc: &6 2016-08-04 02:11:06.557227000 Z
zone: &8 !ruby/object:ActiveSupport::TimeZone
name: Etc/UTC
time: *6
updated_at: !ruby/object:ActiveRecord::Attribute::FromDatabase
name: updated_at
value_before_type_cast: '2016-08-04 02:11:06.557227'
type: *7
original_attribute:
value: !ruby/object:ActiveSupport::TimeWithZone
utc: &9 2016-08-04 02:11:06.557227000 Z
zone: *8
time: *9
new_record: false
active_record_yaml_version: 1
=> nil
You can also use the pp
to provide better, prettier output:
2.3.1 :006 > pp article
#<Article:0x000000051a8358
id: 1,
title: "Test Article",
body: "Test Article Body",
created_at: Thu, 04 Aug 2016 02:11:06 UTC +00:00,
updated_at: Thu, 04 Aug 2016 02:11:06 UTC +00:00>
You can even view the article as JSON if you want:
2.3.1 :020 > article.as_json
=> {"id"=>1, "title"=>"Test Article", "body"=>"Test Article Body", "created_at"=>Thu, 04 Aug 2016 02:11:06 UTC +00:00, "updated_at"=>Thu, 04 Aug 2016 02:11:06 UTC +00:00}
You can browse the pages of your application using app.get
, app.post
, app.put
, app.patch
, and app.delete
, for example:
2.3.1 :011 > app.get('/')
Started GET "/" for 127.0.0.1 at 2016-08-03 21:16:56 -0500
ActiveRecord::SchemaMigration Load (0.2ms) SELECT "schema_migrations".* FROM "schema_migrations"
Processing by Rails::WelcomeController#index as HTML
Parameters: {"internal"=>true}
Rendering /home/richard/.rvm/gems/ruby-2.3.1/gems/railties-5.0.0/lib/rails/templates/rails/welcome/index.html.erb
Rendered /home/richard/.rvm/gems/ruby-2.3.1/gems/railties-5.0.0/lib/rails/templates/rails/welcome/index.html.erb (6.9ms)
Completed 200 OK in 45ms (Views: 22.3ms | ActiveRecord: 0.0ms)
=> 200
This allows you to quickly and easily debug an issue. Once you perform one of the above actions, you can access the cookies with app.cookies
:
2.3.1 :014 > app.cookies
=> #<Rack::Test::CookieJar:0x00000004f6e8d0 @default_host="www.example.com", @cookies=[]>
You can also access the flash via app.flash
:
2.3.1 :012 > app.flash
=> #<ActionDispatch::Flash::FlashHash:0x000000046ad8b8 @discard=#<Set: {}>, @flashes={}, @now=nil>
You can access the parameters for the request via app.controller.params
:
2.3.1 :011 > app.controller.params
=> <ActionController::Parameters {"home"=>"true", "controller"=>"homes", "action"=>"show"} permitted: false>
You can even access session variables with app.session
:
2.3.1 :010 > app.session[:home]
=> "true"
In previous versions of Rails you could access instance variables with app.assigns(:variable_name)
. Note that this functionality has been removed in Rails 5 and extracted to the rails-controller-testing
gem so you will need to include it if you wish to use this functionality.
Want to see your routes? You can:
2.3.1 :026 > app.methods.grep(/_path$/).sort
=> [:edit_polymorphic_path, :new_polymorphic_path, :polymorphic_path, :rails_info_path, :rails_info_properties_path, :rails_info_routes_path, :rails_mailers_path, :root_path]
You can resolve routes as well:
2.3.1 :016 > app.root_path
=> "/"
You can call the built in view helpers:
2.3.1 :017 > helper.pluralize(2,'car')
=> "2 cars"
You can even call your own helpers:
2.3.1 :001 > helper.random_color
=> "red"
A few other notes: First, if a redirect URL is set, you can access it with app.response.redirect_url
. Also, you can perform AJAX requests by setting xhr to true, for example: app.get "/?home=true", xhr: true
. Handy, right?
You can get the location of the source code for your methods using the source_location
method, for instance:
2.3.1 :009 > location = helper.method(:random_color).source_location
=> ["/mnt/c/Users/betam/Documents/GoogleDriveExample/app/helpers/application_helper.rb", 2]
You can start console commands using the backtick key (`
), make sure to add one to the end of the line as well. You can then store the output of that command in a variable. For example:
2.3.1 :006 > result = `ls`
=> "app\nbin\nconfig\nconfig.json\nconfig.ru\ndb\nGemfile\nGemfile.lock\nlib\nlog\npublic\nRakefile\nREADME.md\ntest\ntmp\nvendor\n"
2.3.1 :007 > result
=> "app\nbin\nconfig\nconfig.json\nconfig.ru\ndb\nGemfile\nGemfile.lock\nlib\nlog\npublic\nRakefile\nREADME.md\ntest\ntmp\nvendor\n"
Of course, we can also open the source file mentioned earlier in our favorite editor:
2.3.1 :010 > `subl #{location[0]}:#{location[1]}`
Finally, If you make code changes you can reload with reload!
That's it! Thanks for reading!