Archive for January, 2009
sharing common properties between datamapper models
January 17th, 2009 •
tags: datamapper, ruby
require "rubygems"
require "dm-core"
module Locatable
# using a lambda instead of self.included(base) class_eval hack
# to add properties and/or associations that are shared by many models
#
# use this module in two steps.
#
# 1) eval the lambda with property definitions in class scope
# class_eval &Locatable::PROPERTIES
#
# 2) include the common instance methods if any
# include Locatable
#
# this also makes it possible, that this module gets included at a different
# time (place in code) than the property definitions, which might come in
# handy in situations where you deal with overriding methods with/from
# this module (say you want to establish aliases for methods that only get
# added by some calls to belongs_to or has or the likes)
PROPERTIES = lambda do
property :location_id, Integer, :nullable => false
end
ASSOCIATIONS = lambda do
belongs_to :location
end
# common instance methods
# need to support different protocol
# for whatever reason ...
alias :information :description
def latitude
location.latitude
end
def longitude
location.longitude
end
# ...
end
class Item
include DataMapper::Resource
# properties
property :id, Serial
property :owner_id, Integer, :nullable => false
# using the lambda here makes it very explicit what's going on.
# it also allows to preserve the property order in the underlying
# table definition in a natural and consistent way.
class_eval &Locatable::PROPERTIES
property :name, String
property :description, Text
# associations
# again, using the lambda here makes it very explicit what's going on.
class_eval &Locatable::ASSOCIATIONS
belongs_to :owner
has n, :item_categories
has n, :categories, :through => :item_categories
# include Locatable methods after #description exists
# we want to support the alias
include Locatable
end