Archive for January, 2009

sex spam

“Even Godzilla was never this huge”

sharing common properties between datamapper models

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