Even when I’m panicking I’m a fan of datamapper. I like how clean it generally makes my code, but I do notice that I tend to have the same queries cropping up from time to time either in the same application or in other apps using my model library. This just wasn’t dry enough for me, so I made dm-is-viewable. It gives sql-like view functionality to DataMapper Resources. It’s a pretty simple plugin, but lets take a look, um kay?
Let’s start with a really simple User class…
class User
include DataMapper::Resource
belongs_to :location
property :id, Serial
property :name, String
property :username, String
property :password, String
property :gender, String
property :age, Integer
property :favorite_color, String
property :favorite_number, Integer
end
class Location
include DataMapper::Resource
has n, :users
property :id, Serial
property :name, String
property :desc, String
end
Making your resource viewable is pretty easy, first grab the dm-is-viewable gem, then say that your resource is viewable. Views take the exact same parameters that you could pass to Resource.all. The only difference is that dm-is-viewable stores them until they are called.
class User
include DataMapper::Resource
is :viewable
#lets create some views
create_view :legal_women, :gender => 'female', :age.gt => 18
create_view :serial_killers, :favorite_number => 666, :favorite_color => 'black'
#... Resource code *SNIP SNIP*
end
See the befores and afters below:
# Legal Women Before
User.all(:gender => 'female', :age.gt => 18)
# Legal Women After
User.view :legal_women
# Serial killers before
User.all(:favorite_number => 666, :favorite_color => 'black')
# Serial killers after
User.view :serial_killers
# You can also pass further limiting query parameters to #view.
# Legal Local Women Before
User.all(:gender => 'female', :age.gt => 18, User.location.name => 'Los Angeles')
# Legel Local Women After
User.view :legal_women, User.location.name => 'Los Angeles'
# Passing additional parameters FURTHERS the limitation of records, so..
User.view :legal_women, :gender => 'male'
# => Would return nil, the query would essentially be generated as:
# SELECT * from users where gender = 'male' and gender = 'female'
Simply, clean, useful. Woot.