2011-03-23 146 views
1

我使用學說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

我嘗試推行不同的變化的跟蹤策略,但我不能起牀工作的更新。

最後,我實現,因爲對象是通過引用傳遞它未檢測的變化。所以文檔的簡單更新沒有被發現,因爲它與原始文檔相比是相同的參考。

解決的辦法是進行更改時克隆對象:

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

回想起來,雖然使用更改跟蹤的「通知」是比較煩瑣,我認爲它仍然是一個更好的解決方案的策略。但現在我只會在以後克隆和重構。

0

您可能需要使用不同的變化跟蹤政策。在這種情況下,我會去與Notify

+0

我試過這個,但無法讓它工作。我有一個替代工作。 – Cobby 2011-03-25 00:20:28