MongoMapper Родительское Наследование - PullRequest
7 голосов
/ 05 января 2010

Я пытаюсь получить лучший и организованный результат от использования наследования классов с MongoMapper, но у меня возникли некоторые проблемы.

class Item
  include MongoMapper::Document

  key :name, String
end

class Picture < Item
  key :url, String
end

class Video < Item
  key :length, Integer
end

Когда я запускаю следующие команды, они не совсем возвращают то, что я ожидаю.

>> 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?">]

Это все один и тот же результат, я бы ожидал, что Item.all перечислит все результаты, включая себя, Picture и Video. Но если элемент на самом деле Picture, я бы хотел, чтобы он был возвращен, если я запустил Picture.all, а не если я Video.all. Вы понимаете, о чем я?

Я неправильно понимаю, как наследование здесь работает? Если я, какой лучший способ повторить такое поведение? Я пытаюсь следовать этому (пункт 2) в качестве руководства, как я хочу эту работу. Я предполагаю, что он может запустить Link.all, чтобы найти все ссылки, и не включать все остальные классы, которые наследуются от Item. Я не прав?

1 Ответ

10 голосов
/ 06 января 2010

Пример, на который вы ссылаетесь, немного вводит в заблуждение (или, возможно, просто трудно следовать), поскольку он не показывает полное определение для модели Item. Чтобы использовать наследование в ваших моделях, вам нужно определить ключ _type в родительской модели. MongoMapper затем автоматически установит этот ключ на имя класса фактического класса этого документа. Так, например, ваши модели теперь будут выглядеть так:

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

и результат ваших поисков (при условии, что вы создали Picture объект) превратится в:

>> 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?">]
...