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!