У меня возникли проблемы с созданием документа Mongoid, который содержит массив пользовательских объектов.Обработка массивов пользовательских объектов в Mongoid
В моем конкретном случае я намерен хранить массив объектов BaseDevice
. Класс BaseDevice
уже расшифрован и сериализуется от/до простого хэша с помощью поддержки Mongoid custom fields. Это очень хорошо работает на одном объекте.
Для хранения массива BaseDevice
, я создал следующий класс:
class BaseDeviceArray < Array
class << self
def demongoize(object)
object ? object.map{ |obj| BaseDevice.demongoize obj } : new
end
def evolve(object)
case
when BaseDeviceArray then object.mongoize
else object
end
end
end
def mongoize
self.map(&:mongoize)
end
end
Mongoid документ выглядит следующим образом
class MongoPeriph
include Mongoid::Document
field :devices, type: BaseDeviceArray
end
Допустим some_devices
массив, содержащий два BaseDevice
экземпляров. Происходит следующее: когда я назначаю some_devices
полям устройств экземпляра MongoPeriph
, который работает правильно.
mp = MongoPeriph.create
mp.devices = some_devices
mp.devices # => [#<BaseDevice:0x007fa84bac0080>,#<BaseDevice:0x007fa84baaff78>]
При попытке отправить push
, pop
, shift
, unshift
методы в области устройств в Mongoid документе, ничего не кажется, происходит. Изменения не отображаются на объекте mp
. Также при ссылке на один из объектов по индексу (т. Е. При вызове mp.devices[0].some_method
) мир не изменяется.
Когда popping объектов из массива, на каждый pop
дан новый объект. Ожидается, что десериализатор создает экземпляр нового объекта BaseDevice
для каждого pop
, но внутреннее поле не обновляется, то есть объект остается там, и можно бесконечно всплывать.
Использование BaseDeviceArray
отдельно от Mongoid документа работает, как ожидалось:
foo = BaseDeviceArray.new
foo << BaseDevice.new
результаты в массиве с объектом BaseDevice.
КПП. Я нашел в этом другом approach. Это более обобщенный способ реализовать то, что мне нужно, но это monkey-patches Mongoid. Что-то я стараюсь избегать. Более того, это решение, похоже, имеет ту же проблему, что и мой подход.
Добавление этих отношений привело к 'NoMethodError: undefined method '[]' для nil: NilClass из' ... '/mongoid-4.0.2/lib/mongoid/relations/accessors.rb: 113: in 'needs_no_database_query?' 'Кажется, он хочет, чтобы я полностью «mongoize» класса BaseDevice (и производного) с полями и т. Д. То, что я _trying_, чтобы достичь должен иметь простой объект (в массиве), встроенный в файл mongoid. – Rogier
Я не знаю точно, что квалифицирует объект для возможности его встроить в документ. Я полагал, что присутствующие методы de/mogoize должны сделать его «квалифицированным» объектом mongo. В то же время я более или менее работаю со встроенными отношениями. Я забыл добавить 'super' в' BaseDevice'initializer, который отбросил мангоид с его трека. После включения «Mongoid :: Attributes :: Dynamic» это работает. Во всяком случае, я предпочел бы иметь «простой» объект без всякого монго-беспорядка. – Rogier