Проблема с пользовательским типом отображения - PullRequest
1 голос
/ 24 марта 2011

Я использую Doctrine ODM и пытаюсь создать пользовательский тип отображения, но у меня возникли некоторые проблемы.Мой тип отображения аналогичен типу коллекции, но вместо этого он работает с ArrayCollection:

<?php
class ArrayCollectionType extends Type
{

    public function convertToDatabaseValue($value)
    {
        return $value !== null ? array_values($value->toArray()) : null;
    }

    public function convertToPHPValue($value)
    {
        return $value !== null ? new ArrayCollection($value) : null;
    }

    public function closureToMongo()
    {
        return '$return = $value !== null ? array_values($value->toArray()) : null;';
    }

    public function closureToPHP()
    {
        return '$return = $value !== null ? new \Doctrine\Common\Collections\ArrayCollection($value) : null;';
    }

}

Однако, когда я обновляю документ, он не записывает изменения из коллекции;начальное постоянное работает отлично.Я выполнил небольшую отладку, чтобы выяснить, что UnitOfWork (не) не вычисляет изменения.

Вот мой тестовый код: Документ:

<?php

namespace Application\Blog\Domain\Document;

use Cob\Stdlib\String,
    Doctrine\Common\Collections\ArrayCollection;

/**
 * Blog category
 *
 * @Document(repositoryClass="Application\Blog\Domain\Repository\BlogRepository", collection="blog")
 */
class Category
{

    /**
     * @Id
     */
    private $id;

    /**
     * @Field(type="arraycollection")
     */
    private $slugs;

    public function __construct()
    {
        $this->slugs = new ArrayCollection();
    }

    public function getId()    
    {
        return $this->id;
    }

    public function getSlugs()
    {
        return $this->slugs;
    }

    public function addSlug($slug)
    {
        $this->slugs->add($slug);
    }

}

Служба:

<?php

$category = new Category("Test");
$category->addSlug("testing-slug");
$category->addSlug("another-test");
$this->dm->persist($category);
$this->dm->flush();
$this->dm->clear();
unset($category);

$category = $this->dm->getRepository("Application\Blog\Domain\Document\Category")->findOneBy(array("name" => "Test"));
$category->addSlug("is-it-working");
$this->dm->persist($category);
$this->dm->flush();
var_dump($category->getSlugs());

Ожидаемый результат:

object(Doctrine\Common\Collections\ArrayCollection)[237]
  private '_elements' => 
    array
      0 => string 'testing-slug' (length=12)
      1 => string 'another-test' (length=12)
      2 => string 'is-it-working' (length=13)

Фактический результат

object(Doctrine\Common\Collections\ArrayCollection)[237]
  private '_elements' => 
    array
      0 => string 'testing-slug' (length=12)
      1 => string 'another-test' (length=12)

Ответы [ 2 ]

2 голосов
/ 25 марта 2011

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

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

Решение заключается в клонировании объекта при внесении изменений:

public function addSlug($slug)
{
    $this->slugs = clone $this->slugs;
    $this->slugs->add($slug);
}

В ретроспективе, хотя использование политики отслеживания изменений «уведомлять» более обременительно, я думаю, что это все же лучшее решение. Но сейчас я просто клонирую и реорганизую позже.

0 голосов
/ 24 марта 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...