In general on my blog, I'll point out a few features that I felt were incompletely explained in the documentation. Here I address how to use alternative naming for associations.
Using non-default naming for associations
By default, associations are named after the class name:
class Plum
include MongoMapper::Document
one :pit
end
class Pit
include MongoMapper::EmbeddedDocument
end
Running the following to create a Plum with a Pit:
p = Plum.new
p.build_pit
p.save
will result in a document in mongodb like this:
{
"_id" : ObjectId("4f9ff50ba0b7f9b71500004a"),
"pit" : {
"_id" : ObjectId("4f9ff51ba0b7f9b71500004b")
}
}
However, what if you want to have the class called Pit, but have the association name called dapit? Well, you can use the :class option when declaring the association:
class Pit; end
class Plum
include MongoMapper::Document
one :dapit, :class => Pit
end
class Pit
include MongoMapper::EmbeddedDocument
embedded_in :plum
end
Notice that in the above, I needed to declare the class of the embedded document ahead of time, so that I could refer to it in the class definition of Plum.
With the above associations, you can do the following:
p = Plum.new
p.build_dapit
p.dapit.class.name
# => "Pit"
You can do the same with a non-embedded association:
class Pit; end
class Plum
include MongoMapper::Document
one :dapit, :class => Pit
end
class Pit
include MongoMapper::Document
belongs_to :plum
end
With this version you can do the following:
p = Plum.new
p.create_dapit
p.save
p.dapit.plum
However, what if you want to rename the belongs_to association back to plum? This is a bit more complicated. You need to also specify the foreign_key so that both directions of the association use the same key name for the ObjectID:
class Pit; end
class Plum
include MongoMapper::Document
one :dapit, :class => Pit, :foreign_key => :daplum_id
end
class Pit
include MongoMapper::Document
belongs_to :daplum, :class => Plum
end
You might wonder, why do I specify the foreign key daplum_id when I'm declaring the association to dapit. Well, for one associations, the ObjectID of the referring Plum is stored in the pit collection. Then when the pit is requested, MongoMapper find the pit document that points back to the plum. So the key name that needs to be changed to match da new naming convention is plum_id -> daplum_id and it's stored in the pit collection, but this renaming is declared in the Plum class, not the Pit class.
You can use the above version as follows:
p = Plum.new
p.create_dapit
p.save
p.dapit.daplum
And the document for a pit now looks like this, using the alternatively named key:
{
"_id" : ObjectId("4fa0002aa0b7f9653800002b"),
"daplum_id" : ObjectId("4fa00026a0b7f9653800002a")
}
Hope that all makes sense.
No comments:
Post a Comment