This is a little hack I came up with today when I got tired of duplicating logic in scopes and accessor methods. If I define a method in a model like this:
class Submarine < ActiveRecord::Base named_scope :on_surface, :conditions => {:location => 'surface'} named_scope :submerged, :conditions => {:location => 'under water'} end
I should be able to interrogate the model like this without needing to define Submarine#on_surface? or Submarine#submerged?:
sub = Submarine.first => #<Submarine id: 1, location: 'surface'> sub.on_surface? => true sub.submerged? => false
This version contains a preliminary attempt at parsing simple conditions against a model’s attributes, with a fallback to the database for complicated conditions. Which means that some methods will hit your database on each call. Something to be aware of.
The big problem here is that an object’s state is not always in sync with the database. I’ve thought about this a lot, and at this point I think it’s best to raise an exception when using these methods on dirty objects. I think handling dirty objects is beyond the scope of this little hack.
Copyright © 2009 Jim Benton, released under the MIT license