Получите объект дочернего типа вместо родительского из MongoDB


Я пытаюсь извлечь объект из MongoDB, но я столкнулся с проблемой, что он возвращает элемент базового типа вместо дочернего, и это вызывает проблемы, я понял, что это каким-то образом зависит от значения свойства.

/**
 * @MongoDB\Document(
 *     collection="zoo",
 *     repositoryClass="ZooRepository",
 * )
 */
class Zoo
{
    /**
     * @MongoDB\ReferenceMany(targetDocument="Animal", inversedBy="zoo", strategy="addToSet")
     * @var \Doctrine\Common\Collections\ArrayCollection
     */
    protected $animals;


    /**
     * @return mixed
     */
    public function getAnimals()
    {
        return $this->animals->toArray();
    }

    //Some more code

}


/**
 * @MongoDB\Document(
 *     repositoryClass="AnimalRepository",
 *     collection="animals"
 * )
 * @MongoDB\InheritanceType("SINGLE_COLLECTION")
 * @MongoDB\DiscriminatorField("discriminator")
 * @MongoDB\DiscriminatorMap({
 *     "animal"="Animal",
 *     "birds"="Bird",
 *     "mamals"="Mamals"})
 */
class Animal
{
    /**
     * @MongoDB\ReferenceMany(targetDocument="Location", mappedBy="animals", simple=true, cascade={"persist"})
     *
     * @Assert\Count(min="0", max="1")
     */
    protected $locations;
}


/**
 * @MongoDB\Document(repositoryClass="AnimalRepository")
 */
class Bird extends Animal
{

}

/**
 * @MongoDB\Document(repositoryClass="AnimalRepository")
 */
class Mamals extends Animal
{

}

Проблема в том, что когда я вызываю GetAnimals() из ZooHandler, он возвращает объект типа Animal. Что мне нужно, так это тип Млекопитающих или Птиц. Странно то, что если у меня есть элемент в Животных->местоположение, то я все правильно понял (Мамал/Птица) и если в нем нет элемента, то я получил базовый тип.

Если я получу список всех животных непосредственно из AnimalRepository в AnimalHandler, я получу объекты Mamals/Bird соответственно.

ОТРЕДАКТИРОВАНО: Объект зоопарка

> db.zoo.findOne()
{
    "_id" : ObjectId("5822bd23085f753b5a5a2408"),
    "name" : "Zoo 2",
    "active" : true,
    "archived" : false,
    "animals" : [
        DBRef("animals", ObjectId("556cc7adec045b1a0c8b4567"),{ "$db": "tester", "discriminator": "Test\\Bundle\\Core\\Document\\Animal" }),
        DBRef("animals", ObjectId("556cb3b0ec045bbf068b4582"),{ "$db": "tester", "discriminator": "Test\\Bundle\\Core\\Document\\Animal" })
    ]
}

Наверняка есть еще несколько свойств, которые не показаны, так как они не имеют значения.

Author: Tester, 2016-12-20

2 answers

Если я правильно понимаю вашу проблему, вам нужен встроенный PHP get_class() или get_called_class() функции.

Примечание: Сами объекты не должны забывать, к какому классу они принадлежат, даже если они возвращаются функцией/методом, который только "знает", что они возвращают некоторый экземпляр суперкласса или один из его подклассов. Таким образом, вы всегда должны иметь возможность запросить, к какому классу принадлежит экземпляр, с помощью get_class($instance) функция.

 0
Author: Matthew Slyman, 2017-06-06 07:10:35

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

 0
Author: Tester, 2017-10-11 17:52:10