Подтвердить что ты не робот

Как ссылаться на встроенный документ в Mongoid?

Используя Mongoid, скажем, у меня есть следующие классы:

class Map
  include Mongoid::Document

  embeds_many :locations
end

class Location
  include Mongoid::Document

  field :x_coord, :type => Integer
  field :y_coord, :type => Integer

  embedded_in      :map, :inverse_of => :locations
end


class Player
  include Mongoid::Document

  references_one   :location
end

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

Используя этот подход, я получаю следующую ошибку, когда пытаюсь ссылаться на атрибут "location" класса Player:

Mongoid::Errors::DocumentNotFound: Document not found for class Location with id(s) xxxxxxxxxxxxxxxxxxx.

Я понимаю, что это связано с тем, что документ местоположения встроен, что затрудняет ссылку за пределы его документа внедрения (Карта). Это имеет смысл, но как я могу моделировать прямую ссылку на встроенный документ?

4b9b3361

Ответ 1

Поскольку Maps - это их собственная коллекция, вам нужно будет перебирать каждый поиск коллекции карт внутри местоположения, на которое ссылается ваш плеер.

Вы не можете напрямую обращаться к встроенным документам. Вы должны войти в коллекцию и проложить свой путь.

Чтобы избежать повторения всех Карт, вы можете сохранить как ссылку "Место", так и ссылку "Карта" в документе "Игрок". Это позволяет вам привязать критерии, которые выбирают вашу карту, а затем местоположение внутри нее. Вы должны закодировать метод в своем классе Player, чтобы справиться с этим.

def location
  self.map.locations.find(self.location_id)
end

Итак, похоже на то, как вы ответили сами за себя, кроме того, что вы сохранили location_id в документе вашего игрока вместо использования атрибутов кодов.

Другим способом было бы поместить Карты, местоположения и игроки в свои собственные коллекции, а не встраивать местоположение в вашу коллекцию карт. Тогда вы могли бы использовать ссылочные отношения, не делая ничего необычного... однако на самом деле, просто используя иерархическую базу данных, она нравится реляционной базе данных на этом этапе...

Ответ 2

ПОЖАЛУЙСТА, и VOTE для функции "виртуальных коллекций" в отслеживателе проблем MongoDB:

http://jira.mongodb.org/browse/SERVER-142

Это вторая самая запрошенная функция, но она еще не была запланирована для выпуска. Может быть, если достаточно людей проголосуют за него и переведут его на номер один, команда MongoDB, наконец, выполнит его.

Ответ 3

В моем случае использования внешнему объекту не требуется ссылаться на встроенный документ. Из группы пользователей mongoid я нашел решение: используйте ссылочный_индекс во встроенном документе и ссылку NO на внешний документ.

class Page
  include Mongoid::Document
  field :title

  embeds_many :page_objects
end

class PageObject
  include Mongoid::Document
  field :type

  embedded_in       :page,    :inverse_of => :page_objects
  referenced_in     :sprite
end

class Sprite
  include Mongoid::Document
  field :path, :default => "/images/something.png"
end

header_sprite = Sprite.create(:path => "/images/header.png")
picture_sprte = Sprite.create(:path => "/images/picture.png")

p = Page.create(:title => "Home")
p.page_objects.create(:type => "header", :sprite => header_sprite)
p.page_objects.first.sprite == header_sprite

Ответ 4

Мое текущее обходное решение заключается в следующем:

class Map
  include Mongoid::Document

  embeds_many     :locations
  references_many :players, :inverse_of => :map
end

class Player
  referenced_in :map
  field :x_coord
  field :y_coord

  def location=(loc)
    loc.map.users << self
    self.x_coord = loc.x_coord
    self.y_coord = loc.y_coord
    self.save!
  end

  def location
    self.map.locations.where(:x_coord => self.x_coord).and(:y_coord => self.y_coord).first
  end  
end

Это работает, но чувствует себя как kluge.

Ответ 5

Мышление вне поля, вы можете сделать свой собственный документ и использовать Mongoid Alize для автоматического создания встроенных данных в вашем документе карты из ваших документов местоположения.

https://github.com/dzello/mongoid_alize

Преимущество этого метода заключается в том, что вы получаете эффективные запросы, когда подходят условия, и медленные запросы на основе ссылок на исходный документ, когда нет другого пути.