The Pug Automatic

Raising finders

Written June 24, 2007. Tagged Ruby, Ruby on Rails.

I find exceptions preferable to if/else branching in many cases.

Though Rails has save! and create! methods that raise exceptions if they fail, the same can not be said for finders. User.find(123) will raise ActiveRecord::RecordNotFound if there's no record with that id, but other finders (find(:all, …), find(:first, …) and dynamic finders like find_by_username(…)) will just return nil or an empty array.

Adding this has been discussed, and there is a slumbering ticket.

This is my take. require 'raising_finders' in environment.rb and put this in lib/raising_finders.rb:

# Enables methods like find!(:all, …), find_by_username!(…) that
# raise ActiveRecord::RecordNotFound for empty results.

module RaisingFinders
def method_missing(name, *args)
return super unless name.to_s =~ /^(find(_.+)?)!$/
returning send($1, *args) do |result|
raise ActiveRecord::RecordNotFound if result.blank?
end
end
end

class << ActiveRecord::Base
include RaisingFinders
end

While writing this, I found I was reinventing the wheel – there is a whiny_finder plugin that's functionally equivalent – but I find that code a bit wordy. My wheel is rounder!