Category: Ruby

  • Silencing noise in the Rails development log

    The standard Rails development log contains a lot of noise that is rarely meaningful for debugging. The Quiet Assets gem is a mandatory part of my Rails development process as it removes the logging noise of the asset pipeline.

    Also, if WEBrick is used as a development server, the following entry is logged for each asset pipeline log entry (whether silenced or not by Quiet Assets):

    WARN Could not determine content-length of response body.
    Set content-length of the response or set Response#chunked = true
    

    While some have suggested monkey-patching WEBrick or installing Thin as an alternate server (which doesn’t work under JRuby), the simplest way to remove those statements is to add WEBrick specifically in your Gemfile:

    gem 'webrick', '~> 1.3.1', group: :development
    
  • Mixing DatabaseCleaner transaction and truncation strategies

    RSpec by default issues a database transactional rollback that is executed after the completion of a block. When using Capybara with the :js option (to enable testing with Selenium or Webkit), the transactional rollback offered by RSpec is unusable as the browser is loaded via a separate thread and has a separate database connection. Thus any uncommitted data cannot be read by the browser.

    Most people suggest employing DatabaseCleaner using a truncation strategy to overcome this deficiency. The performance of cleaning via truncation vs transaction depends on the size of data – with smaller fixtures, transactions are preferable.
    Instead of using one or the other, we can mix strategies to have the best of both worlds:

    config.use_transactional_fixtures = false # Using DatabaseCleaner instead
    
    config.before(:suite) do
    DatabaseCleaner.strategy = :transaction # Default strategy
    DatabaseCleaner.clean_with(:truncation) # Initially clean with truncation
    end
    
    config.before(:each, type: :request) do
    # Swap to truncation as Selenium runs in separate thread with a different
    # database connection
    DatabaseCleaner.strategy = :truncation
    end
    
    config.after(:each, type: :request) do
    # Reset so non-request specs can use transaction
    DatabaseCleaner.strategy = :transaction
    end
    
    config.before(:each) do
    DatabaseCleaner.start
    end
    
    config.after(:each) do
    DatabaseCleaner.clean
    end
    

    On my current test suite of around 461 tests with 73 request specs, this dropped the run time by just over a minute.

  • Mocking instances created via ActiveRecord’s find

    Most Ruby mocking frameworks have the ability to mock a new object created via a constructor. However, when an object is created via ActiveRecord’s find or find_by_* methods, the .new method isn’t invoked. Instead, the .instantiate method is called.

    For example, to specify :instantiate as the object creation method using FlexMock:

    flexmock(Dog).new_instances(:instantiate)
    .should_receive(:bark)
    .at_least.once
    .and_return(:woof)
    
  • Persisting IRB & Rails Console History

    Continuing the theme on customising IRB and Rails Console, add these lines to ~/.irbrc to persist the command history across console sessions:

    require 'irb/ext/save-history'
    IRB.conf[:SAVE_HISTORY] = 100
    IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb_history"
    
  • Awesome Print your IRB & Rails Console

    Awesome Print is a Ruby gem that prints prettified objects to the console. To avoid having to prepend ap to all your console commands, set it as the default formatter in IRB and Rails by adding the following to your ~/.irbrc:

    require 'awesome_print'
    IRB::Irb.class_eval do
    def output_value
    ap @context.last_value
    end
    end
    

    Obviously, Awesome Print first needs to be installed: gem install awesome_print

    UPDATE: Awesome Print now includes a method to make the integration process easier.

    require 'awesome_print'
    AwesomePrint.irb!