Skip to content

Instantly share code, notes, and snippets.

@BrianTheCoder
Created September 11, 2009 22:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BrianTheCoder/185630 to your computer and use it in GitHub Desktop.
Save BrianTheCoder/185630 to your computer and use it in GitHub Desktop.
module Habtm
def self.included(model)
model.extend ClassMethods
end
module ClassMethods
def habtm(name, opts = {})
klass = opts.delete(:model) || name.to_s.classify
resource_klass = [klass, self].map{|k| k.to_s }.sort.join('')
storage_name = Extlib::Inflection.tableize(resource_klass)
field = name.to_s.singular
self_klass = self.to_s.snake_case
has n, storage_name.to_sym
resource = DataMapper::Model.new(storage_name)
resource.property :"#{self_klass}_id", Integer, :key => true, :unique => [ :"#{field}_id" ]
resource.property :"#{field}_id", Integer, :key => true
resource.belongs_to :"#{self_klass}"
resource.belongs_to :"#{field}"
begin
Object.const_get(resource_klass)
rescue
Object.const_set(resource_klass, resource)
end
class_eval <<-RUBY
def #{name}
#{klass}.all(:id => #{field}_ids)
end
def #{field}_ids
@#{field}_ids = #{resource_klass}.all(:#{self_klass}_id => self.id, :fields => [ :#{field}_id ] ).map{|r| r.#{field}_id }
end
def #{name.to_s.singular}_ids=(ids)
ids = ids.split(',') if ids.is_a?(String)
old_ids = #{field}_ids
(old_ids - ids).each do |remove_id|
#{resource_klass}.first(:#{field}_id => remove_id, :#{self_klass}_id => self.id).destroy
end
(ids - old_ids).each do |add_id|
#{storage_name} << #{resource_klass}.new(:#{field}_id => add_id, :#{self_klass}_id => self.id)
end
@#{field}_ids = ids
end
RUBY
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment