Dynamic bang finders in Rails 4


I propose to add #where! finder that raises an exception if the relation is empty like find_by_xxx! method in Rails3.

Rails 4 is getting rid of dynamic finders, so



User.where(hash: hash) # .first

Okay, not a big deal. But what is the best way to deal do with dynamic bang finders like User.find_by_hash!(hash) since there is no where!() method?

A suggestion I got on Stackoverflow (http://stackoverflow.com/questions/14372963/dynamic-bang-finders-in-rails-4/15257207) is to add a #where! method.

If you need a method that finds all but raises exception if the relation is empty, you can create such new method for your models yourself (or mixin to ActiveRecord::QueryMethods). Something like:

def where!(*args)

	  rel = where(*args) 

	  raise RecordNotFound if rel.empty?



No, those ‘dynamic finders’ based on your attribute names aren’t get removed. If you have an attribute name hash, you should be able to still do User.find_by_hash!

See the list of deprecated methods here: http://edgeguides.rubyonrails.org/4_0_release_notes.html#active-record-deprecations


Wouldn’t it be more intuitive to use the #first! method for this purpose?

i.e., User.find_by_hash!(hash) is the same as User.where(hash: hash).first!

I know that I often chain where conditions together (especially when using scopes), so it makes sense to raise the exception only when I actually try to fetch the record from the database.

or User.find_by! hash: hash


Francesco Rodríguez
"The Most Powerfull Rookie"

@frodsan (http://twitter.com/#!/frodsan)

Oh, right “All dynamic methods EXCEPT for find_by_... and find_by_...! are deprecated.”

Either the pages has changed since or I was blind when reading it.