Monday, June 23, 2008

DataMapper: Many-to-many

You can define many-to-many associations using this syntax:

#item.rb
has n, :things, :through => Resource

#thing.rb
has n, :items, :through => Resource

In this case it will create a table items_things to manage the assignments. Easy enough. Depending on the relationship you are mapping out, it may make more sense to use the :through => :model syntax.

Now if you create an instance of an Item, you will get a method "things=". At first I thought this would be how you would assign a new Thing to your Item. Such as:

@item = Item.get(1)
@thing = Thing.get(1)
@item.things = @thing

FAIL! If you try adding a single Thing to your Item with this method you will receive a failure that the class you sent did not have a map method defined. Ah, ok. That makes sense, things= is obviously plural and will want an array of things. So how do you assign just one thing?

If you are unsure, a handy tool is to remember the "methods" method. So in this case you can try out:

@item.methods

You will see that you have not only a "things=" method, but also a plain old "things" method. If you try:

@item.things.methods

You will see that you have a << method, as should be expected. So to add our single Thing to our Item we do:

@item.things << @thing

That's it.

Friday, June 6, 2008

DataMapper: Parent / Child Relationship

I couldn't find an example at datamapper.org /docs for a parent child relationship.


After a little searching, I found the answer in the integration tests.  Here is the example:

class Node
include DataMapper::Resource

def self.default_repository_name
ADAPTER
end

property :id, Integer, :serial => true
property :name, String

has n, :children, :class_name => 'Node', :child_key => [ :parent_id ]
belongs_to :parent, :class_name => 'Node', :child_key => [ :parent_id ]

end

Hope that helps someone else.