Doctrine - ManyToMany Self Referencing Association +在子元素上嵌套toArray()

时间:2012-10-03 17:13:16

标签: symfony doctrine-orm many-to-many associations self-reference

我正在尝试按照Doctrine文档在我的Symfony 2.1项目中执行ManyToMany自引用关联:http://docs.doctrine-project.org/en/latest/reference/association-mapping.html#many-to-many-self-referencing

我的用例是我正在使用CMS,并且我正在添加具有相关内容项的功能。例如:我可以在网站上有一个侧边栏,可以说这段内容X与Y和Z相关。同样在内容Y出现的页面上,它表示它与内容项X相关。

在我的测试中使用它来添加内容项之间的新关系失败,因为它达到PHP的最大嵌套级别100,因为它在当前内容项上运行toArray(),然后再在相关内容项上运行,依此类推等等。

我已经看到很多类似的问题,关于多对多自我引用的学说关联,但没有一个有足够的完整代码,以便能够看到其他人如何管理这个。有人可以帮忙吗?

我的内容实体:

/**
 * @ORM\MappedSuperclass
 * @ORM\Table(name="content")
 * @ORM\Entity(repositoryClass="CMS\Bundle\Common\ContentBundle\Entity\ContentRepository")
 * @ORM\InheritanceType("JOINED")
 */
abstract class content implements ContentInterface
{
    /**
     * @var int $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string $title
     *
     * @ORM\Column(name="title", type="string", length=255)
     * @Assert\NotBlank()
     */
    private $title;

    // Other class properties

    /**
     * @var array
     *
     * @ORM\ManyToMany(targetEntity="Content", cascade={"persist"})
     * @ORM\JoinTable(name="content_relation",
     *      joinColumns={@ORM\JoinColumn(name="relation_id", referencedColumnName="id")},
     *      inverseJoinColumns={
     *          @ORM\JoinColumn(name="related_content_id", referencedColumnName="id")
     *      })
     **/
    private $related;

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

    // Other getters & setters for class properties

    /**
     * @return array
     */
    public function getRelated()
    {
    return $this->related;
    }

    /**
     * @param Content $relation
     */
    public function addRelation(Content $relation)
    {
        $this->related->add($relation);
        $this->related->add($this);
    }

    /**
    * @return array
    */
    public function toArray()
    {
        $related = array();
        foreach($this->getRelated() as $relatedItem) {
        $related[] = $relatedItem->toArray();
    }

    return array(
        'type' => static::getType(),
        'id' => $this->id,
        'title' => $this->title,
        ....
        'related' => $related
    );
}

在我的RelationsController中用于管理相关内容数据,我使用它:

/**
 * Creates a new relation to a content item
 * 
 * @Route("{_locale}/content/{id}/related", name="relation_add")
 * @Method("POST")
 */
public function addAction(Request $request, $id)
{
    // Validation and error checking
    // $entity is loaded by the repository manager doing a find on the passed $id
    $entity->addRelation($relation);

    $em = $this->getEntityManager();
    $em->persist($entity);
    $em->persist($relation);
    $em->flush();

    $response = $relation->toArray();

    return new JsonResponse($response, 201);
}

1 个答案:

答案 0 :(得分:1)

对此的修复是使用JMSSerializerBundle将实体编码为JSON而不是使用toArray方法,并将addRelation函数更改为:

/**
 * @param Content $relation
 */
public function addRelation(Content $relation)
{
    $this->related[] = $relation;

    if (! $relation->getRelated()->contains($this)) {
        $relation->addRelation($this);
    }
}