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!