는 업데이트 : 카테고리와 포스트 사이에 참조 된 관계로 스위치가 jwage의 추천시 : http://bit.ly/gpstW9
업데이트 (2011 5월 5일) : 예쁜 일정이 버그는 락스에 문제를 만든 (Embdedded와 반대).문제 지속 중첩 중첩 된 포함 된 문서
Doctrine ODM (Git의 최신 버전)의 최신 버전을 사용하고 있습니다.
나는 세 가지 수준의 문서 (두 가지 임베디드)를 가지고 있습니다. 카테고리 -> EmbedsMany : Post-> EmbedsMany PostVersion.
PostVersion은 자동으로 Post로 처리됩니다. 새 게시물을 만들 때 사실상 새로운 PostVersion을 만듭니다.
내 문제는 Doctrine이 PostVersions와 혼동되는 것입니다. 기존 카테고리를 검색하고 새 게시물을 추가하면 새 Post의 PostVersions가 카테고리 $ posts 컬렉션의 첫 번째 게시물에 추가됩니다.
단계별 :
- 새로운 포스트 (Post1)를 확인하고 분류
- 카테고리는, 세척, 지우기
- 카테고리를
- 만들기 검색 지속 분류 Post1 추가 새로운 게시물 (게시물 2)
- 게시물에 카테고리를 추가하십시오
- 플러시
데이터베이스의이 단계에는 카테고리 1 개와 게시물 2 개가 있어야하며 각 게시물에는 PostVersion이 하나씩 있어야합니다. 그러나 실제로 발생하는 것은 하나의 카테고리, 두 개의 게시물, 첫 번째 게시물에는 두 개의 PostVersions, 두 번째 게시물에는 PostVersions이 없습니다.
요청 중에 문서 자체가 정확합니다. 데이터베이스에 계속 유지되고 싶을뿐입니다. 내가 뭘 놓치고 있니?
예상 결과 :
{
"_id": ObjectId("4da66baa6dd08df1f6000001"),
"name": "The Category",
"posts": [
{
"_id": ObjectId("4da66baa6dd08df1f6000002"),
"activeVersionIndex": 0,
"versions": [
{
"_id": ObjectId("4da66baa6dd08df1f6000003"),
"name": "One Post",
"content": "One Content",
"metaDescription": null,
"isAutosave": false,
"createdAt": "Thu, 14 Apr 2011 13:36:10 +1000",
"createdBy": "Cobby"
}
]
},
{
"_id": ObjectId("4da66baa6dd08df1f6000004"),
"activeVersionIndex": 0
"versions": [
{
"_id": ObjectId("4da66baa6dd08df1f6000005"),
"name": "Two Post",
"content": "Two Content",
"metaDescription": null,
"isAutosave": false,
"createdAt": "Thu, 14 Apr 2011 13:36:10 +1000",
"createdBy": "Cobby"
}
]
}
]
}
실제 결과 : 여기
{ "_id": ObjectId("4da66baa6dd08df1f6000001"), "name": "The Category", "posts": [ { "_id": ObjectId("4da66baa6dd08df1f6000002"), "activeVersionIndex": 0, "versions": [ { "_id": ObjectId("4da66baa6dd08df1f6000003"), "name": "One Post", "content": "One Content", "metaDescription": null, "isAutosave": false, "createdAt": "Thu, 14 Apr 2011 13:36:10 +1000", "createdBy": "Cobby" }, { "_id": ObjectId("4da66baa6dd08df1f6000005"), "name": "Two Post", "content": "Two Content", "metaDescription": null, "isAutosave": false, "createdAt": "Thu, 14 Apr 2011 13:36:10 +1000", "createdBy": "Cobby" } ] }, { "_id": ObjectId("4da66baa6dd08df1f6000004"), "activeVersionIndex": 0 } ] }
내 문서입니다
Category.php
<?php
namespace Documents\Blog;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @Document(collection="blog")
* @HasLifecycleCallbacks
*/
class Category
{
/**
* @Id
*/
private $id;
/**
* @String
*/
private $name;
/**
* @EmbedMany(targetDocument="Documents\Blog\Post")
*/
private $posts;
public function __construct($name = null)
{
$this->posts = new ArrayCollection();
$this->setName($name);
}
public function getId()
{
return $this->id;
}
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
public function getPosts()
{
return $this->posts->toArray();
}
public function addPost(Post $post)
{
$this->posts->add($post);
}
public function getPost($id)
{
return $this->posts->filter(function($post) use($id){
return $post->getId() === $id;
})->first();
}
}
Post.php
<?php
namespace Documents\Blog;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @EmbeddedDocument
* @HasLifecycleCallbacks
*/
class Post
{
/**
* @Id
*/
private $id;
private $firstVersion;
private $activeVersion;
/**
* @Int
*/
private $activeVersionIndex;
/**
* @EmbedMany(targetDocument="Documents\Blog\PostVersion")
*/
private $versions;
static private $currentUser;
private $isDirty = false;
public function __construct($name = "", $content = "")
{
if(!self::$currentUser){
throw new \BlogException("Cannot create a post without the current user being set");
}
$this->versions = new ArrayCollection();
$this->activeVersion = $this->firstVersion = new PostVersion($name, $content, self::$currentUser);
$this->versions->add($this->firstVersion);
$this->isDirty = true;
}
public function getId()
{
return $this->id;
}
public function getFirstVersion()
{
return $this->firstVersion;
}
public function getActiveVersion()
{
return $this->activeVersion;
}
public function setName($name)
{
$this->_setVersionValue('name', $name);
}
public function getName()
{
return $this->getActiveVersion()->getName();
}
public function setContent($content)
{
$this->_setVersionValue('content', $content);
}
public function getContent()
{
return $this->getActiveVersion()->getContent();
}
public function setMetaDescription($metaDescription)
{
$this->_setVersionValue('metaDescription', $metaDescription);
}
public function getMetaDescription()
{
return $this->getActiveVersion()->getMetaDescription();
}
public function getVersions()
{
return $this->versions->toArray();
}
private function _setVersionValue($property, $value)
{
$version = $this->activeVersion;
if(!$this->isDirty){
// not dirty, make a new version
$version = new PostVersion($version->getName(), $version->getContent(), self::getCurrentUser());
}
$refl = new \ReflectionProperty(get_class($version), $property);
$refl->setAccessible(true);
// updated current user
$refl->setValue($version, $value);
// unset ID
$refl = new \ReflectionProperty(get_class($version), 'id');
$refl->setAccessible(true);
$refl->setValue($version, null);
// updated self
if(!$this->isDirty){
$this->activeVersion = $version;
$this->versions->add($version);
$this->isDirty = true;
}
// no first version, this must be the first
if($this->versions->count() === 1){
$this->firstVersion = $version;
}
}
static public function setCurrentUser($user)
{
self::$currentUser = $user;
}
static public function getCurrentUser()
{
return self::$currentUser;
}
/**
* @PostLoad
*/
public function findFirstVersion()
{
$firstVersion = null;
foreach($this->versions as $version){
if(null === $firstVersion){
// first iteration, start with any version
$firstVersion = $version;
continue;
}
if($version->getCreatedAt() < $firstVersion->getCreatedAt()){
// current version is newer than existing version
$firstVersion = $version;
}
}
if(null === $firstVersion){
throw new \DomainException("No first version found.");
}
$this->firstVersion = $firstVersion;
}
/**
* @PostLoad
*/
public function findActiveVersion()
{
$this->activeVersion = $this->versions->get($this->activeVersionIndex);
}
/**
* @PrePersist
* @PreUpdate
*/
public function doActiveVersionIndex()
{
$this->activeVersionIndex = $this->versions->indexOf($this->activeVersion);
$this->isDirty = false;
}
/**
* @PostPersist
* @PostUpdate
*/
public function makeClean()
{
$this->isDirty = false;
}
public function getCreatedBy()
{
return $this->getFirstVersion()->getCreatedBy();
}
public function getCreatedAt()
{
return $this->getFirstVersion()->getCreatedAt();
}
}
PostVersion.PHP
... xdebug로 더러워 질 시간입니다. 지금은 지연이 중첩 포함 된 문서를 지속 EventSubscriber를 작성하여 문제를 해결 작업 한 내용은
나도 비슷한 일에 약간의 문제가있다. – alex