Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoMapper Parent Inheritance

Tags:

mongomapper

I am trying to get a better and organized result from using class inheritance with MongoMapper, but having some trouble.

class Item
  include MongoMapper::Document

  key :name, String
end

class Picture < Item
  key :url, String
end

class Video < Item
  key :length, Integer
end

When I run the following commands, they don't quite return what I am expecting.

>> Item.all
=> [#<Item name: "Testing", created_at: Sun, 03 Jan 2010 20:02:48 PST -08:00, updated_at: Mon, 04 Jan 2010 13:01:31 PST -08:00, _id: 4b416868010e2a04d0000002, views: 0, user_id: 4b416844010e2a04d0000001, description: "lorem?">]
>> Video.all
=> [#<Video name: "Testing", created_at: Sun, 03 Jan 2010 20:02:48 PST -08:00, updated_at: Mon, 04 Jan 2010 13:01:31 PST -08:00, _id: 4b416868010e2a04d0000002, views: 0, user_id: 4b416844010e2a04d0000001, description: "lorem?">]
>> Picture.all
=> [#<Picture name: "Testing", created_at: Sun, 03 Jan 2010 20:02:48 PST -08:00, updated_at: Mon, 04 Jan 2010 13:01:31 PST -08:00, _id: 4b416868010e2a04d0000002, views: 0, user_id: 4b416844010e2a04d0000001, description: "lorem?">]

They are all the same result, I would expect to have Item.all list all of the results, so including itself, Picture, and Video. But if the item is actually a Picture, I would like it to be returned if I ran Picture.all and not if I run Video.all. Do you see what I mean?

Am I misunderstanding how the inheritance works here? If I am what is the best way to replicate this sort of behavior? I am trying to follow this (point 2) as a guideline of how I want this work. I assume he can run Link.all to find all the links, and not include every other class that inherits from Item. Am I wrong?

like image 432
Garrett Avatar asked Jan 04 '10 21:01

Garrett


1 Answers

The example you link to is a little misleading (or maybe just hard to follow) in that it doesn't show the full definition for the Item model. In order to use inheritance in your models, you'll need to define a key _type on the parent model. MongoMapper will then automatically set that key to the class name of the actual class of that document. So, for instance, you models would now look like this:

class Item
  include MongoMapper::Document

  key :name, String
  key :_type, String
end

class Picture < Item
  key :url, String
end

class Video < Item
  key :length, Integer
end

and the output of your searches (assuming you created a Picture object) will turn into:

>> Item.all
=> [#<Picture name: "Testing", _type: "Picture", created_at: Sun, 03 Jan 2010 20:02:48 PST -08:00, updated_at: Mon, 04 Jan 2010 13:01:31 PST -08:00, _id: 4b416868010e2a04d0000002, views: 0, user_id: 4b416844010e2a04d0000001, description: "lorem?">]
>> Video.all
=> []
>> Picture.all
=> [#<Picture name: "Testing", _type: "Picture", created_at: Sun, 03 Jan 2010 20:02:48 PST -08:00, updated_at: Mon, 04 Jan 2010 13:01:31 PST -08:00, _id: 4b416868010e2a04d0000002, views: 0, user_id: 4b416844010e2a04d0000001, description: "lorem?">]
like image 59
Emily Avatar answered Oct 06 '22 01:10

Emily