2013-09-13 2 views
1

Вот два класса образца у меня есть:Восстановить документ с вложенными документами на ODM

/** @ODM\Document */ 
class Product implements JsonSerializable{ 

    /** @ODM\String */ 
    protected $some_property; 

    /** @ODM\EmbedMany */ 
    protected $attributes; 

    public function jsonSerialize(){ 
    $o = new StdClass(); 
    $o->property = $this->some_property; 
    $o->attributes = $this->attributes; 
    return $o; 
    } 
} 

/** @ODM\EmbeddedDocument */ 
class Attribute implements JsonSerializable{ 

    /** @ODM\String */ 
    protected $some_property; 

    public function jsonSerialize(){ 
    $o = new StdClass(); 
    $o->property = $this->some_property; 
    return $o; 
    } 
} 

В моем коде, я создаю экземпляр продукта, а затем некоторые процессы создают массив экземпляров атрибута $product->attributes. Я сохраняю экземпляр продукта без проблем в mongoDB, используя Doctrine ODM. я могу пойти в БД (с использованием rockmongo), и я вижу presisted документ, и аннотации на представлении JSON к классу attributes массива:

"_doctrine_class_name": "\Attribute" 

Но когда я запрашиваю для этого продукта с помощью QueryBuilder, вместо того, чтобы получать массив экземпляров атрибутов, я получаю PersistentCollection (глядя на isntance с отладчиком во время выполнения).

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

Вот что я ожидаю получить сформировать json_encode():

{ 
    "property": "some product value", 
    "attributes": [ 
     { 
      "property": "some attribute value" 
     }, 
     { 
      "property": "some attribute value" 
     } 
    ] 
} 

Есть ли способ либо отключить отложенной загрузки или заставить надлежащий экземпляр каждого атрибут экземпляра? Или любой другой способ получить желаемый объект JSON без необходимости ручного перемещения всей структуры? Спасибо!

+0

Как насчет использования Doctrine ODM, а только сырой php Mongo? – LFI

+0

Ну ... не так много решения проблемы, так как для однородности мне нужно будет перестроить проект. Но что вы понимаете под сырым php Mongo, и где я могу прочитать некоторые учебники или doc для этого (конкретно в ZF2)? –

+0

Согласен, это не решение. Но IMO вы пытаетесь использовать функции ODM для работы с каким-то динамическим массивом. Если я прав, это просто с [\ MongoClient] (http://www.php.net/manual/en/class.mongoclient.php) или [\ MongoCollection] (http://www.php.net/ manual/en/class.mongocollection.php), поскольку вы работаете непосредственно с массивом. И вы можете получить доступ к нему через doctrine-odm, как этот '$ documentManager-> getConnection() -> getMongo()'. Не уверен, что помощь. – LFI

ответ

2

Как я в конечном итоге решение вопроса о ленивой загрузке:

// parent jsonSerialize method 
public function jsonSerialize(){ 
    $o = new StdClass(); 
    $o->property = $this->some_property; 
    $a = []; 
    foreach($this->attributes as $attr){ 
    $a[] = $attr; 
    } 
    $o->attributes = $a; 
    return $o; 
} 

Это заставляет объект PersistentCollection плюнуть наши один за другим соответствующие инстанции, а затем jsonSerializable методов отзываются хорошо каскаду через.

Уродливая ИМО, но решает проблему. К сожалению, вы должны применить это к каждой зависимой вам встраиваемой объектной среде.

Отверстие помогает!

+0

Чувак, я искал это решение! Но что я не понимаю: каково намерение ODM позволить нам делать эту уродливую вещь? Мы делаем это неправильно? Как это должно быть правильно? – tester

+0

Другим, более чистым решением было бы сделать '$ o-> attributes = $ this-> attributes-> toArray()' вместо ручного цикла. Но все равно уродливо. –

Смежные вопросы