-
Notifications
You must be signed in to change notification settings - Fork 8
Home
Welcome to the discussion on implementing polymorphism for DataMapper. Please comment, update, edit if you’d like to add stuff.
As an example, we’ll use the old blog articles with comments and tags. Comments is the basic case for polymorphism. Tags is the complex via through.
A table that implements polymorphism should have 2 additional fields to facilitate the polymorphism.
property :<interface_name>_class, Class #=> requires a custom setu property :<interface_name>_id, Integer
class Post
include DataMapper::Resource
end
class Comment
include DataMapper::Resource
end
is_polymorphic(interface_name, opts)
Sets up the interface and attaches it to the class. The interface attaches the required two properties to the class class_id and id.
It also registers itself as an available polymorphic interface to the class.
Installs the Klass.commentables and Klass#commentable methods
This is where the real work is done. Currently the idea for polymorphism is to setup a belong_to association on the polymorphic side, and a has n on the owning side. The has_polymorphic method would set these up on each class. In our comment example, when
has_polymorphic :comments, :via => :commentable
is called in the Post class these associations would be set up.
Post.has n, :comments, :child_key => [:commentable_id], :conditions => {:commentable_class => User}
Comment.belongs_to :post, :child_key => [:commentable_id], :local_conditions => { :commentable_class => User }
By implementing polymorphism using existing associations, a great deal of flexibility should result.
In addition to the Post class above.
#Reopen Post from before
class Post
has_polymorphic :taggings, :via => :taggable
end
class Tagging
include DataMapper::Resource
end
class Tag
include DataMapper::Resource
end
The basic polymorphic stuff is setup on on the Tagging model. Then tags are associated through taggings.
So in posts you can have post.tags and get all the tags assocaited with the post.
The tricky part is when going the other way.