Объект представления FOSRest с ассоциацией ManyToMany предотвращает глубоко вложенный массив json

Мое название, вероятно, не самое лучшее; Мне трудно найти краткое описание проблемы.

У меня есть 2 объекта: объект и элемент (с ассоциацией ManyToMany)

Объект:

    <?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * @ORM\Entity(repositoryClass="AppBundle\Repository\ObjectRepository")
 * @ORM\Table(name="object")
 */
class Object {

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     *
     * @ORM\Column(type="string", nullable=true)
     */
    protected $name;

    /**
     * @ORM\ManyToMany(targetEntity="Element", inversedBy="objects", cascade={"persist"})
     * @ORM\JoinTable(name ="objects_elements")
     */
     protected $elements;


     function __toString() {
        return $this->getName();
     }

getters and setters....

И элемент:

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * @ORM\Entity(repositoryClass="AppBundle\Repository\ElementRepository")
 * @ORM\Table(name="element")
 */
class Element {

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     *
     * @ORM\Column(type="string", nullable=true)
     */
    protected $name;

    /**
     * @ORM\ManyToMany(targetEntity="Object", mappedBy="elements", cascade={"persist"})
     */
    private $objects;

getters and setters....

Контроллер расширяет FOSRestController:

<?php

namespace AppBundle\Controller\Api;

use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use AppBundle\Entity\Object;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Controller\Annotations\View;


/**
 * Object controller.
 *
 * @Route("/object")
 */
class ObjectController extends FOSRestController {

    /**
     * Show Object entitie.
     *
     * @Route("/{id}/edit/api", options={"expose"=true}, name="object_show_api")
     * @Method("GET")
     * 
     */
    public function jsonShowAction($id) {
        $em = $this->getDoctrine()->getManager();
        $entity = $em->getRepository('AppBundle:Object')->findOneById($id);

        $view = $this->view($entity
                        , 200)
                ->setTemplate("object/json.html.twig");


        return $this->handleView($view);
    }

Вывод контроллера следующий json:

{
    "object": {
        "id": 10,
        "name": "Object 3",
        "elements": [{
            "id": 1,
            "name": "Element 1",
            "objects": [{
                "id": 1,
                "name": "Object 2a",
                "elements": [],
            }]
        }]
    }
}

Я хочу, чтобы в «элементах» отображался массив «объекты», потому что там снова будут отображаться «элементы» и так далее...

Каков правильный способ добиться этого? Я предпочитаю, чтобы вывод был примерно таким:

{
    "object": {
        "id": 10,
        "name": "Object 3",
        "elements": [{
            "id": 1,
            "name": "Element 1",
        }]
    }
}

Большое спасибо!


person Lex Hartman    schedule 28.08.2016    source источник


Ответы (1)


Вы должны изменить отношения между объектами и элементами, чтобы они были однонаправленными: Сторона объектов:

/**
 * @ORM\ManyToMany(targetEntity="Element", cascade={"persist"})
 * @ORM\JoinTable(name ="objects_elements")
 */
 protected $elements;

Сторона элемента:

null

И проверьте и исправьте возможную ошибку (необязательно):

bin/console doctrine:schema:valid

или для Symfony ‹ 3

app/console doctrine:schema:validate

наконец, удалите старый сеттер/геттер и свойство объектов в классе Element и выполните:

bin/console doctrine:generate:entities YourBundle:Element

Помните, что вам нужно написать пользовательский метод репозитория, такой как getObjects(), из ElementRepository, если вы хотите получить ссылки на все объекты на элемент. Я надеюсь, что это поможет.

person Saint - Cyr MAPOUKA    schedule 28.08.2016
comment
Спасибо. В конце концов я использовал сериализатор jms в сочетании с этим решением: an-object-graph" title="jms serializer как ограничить глубину сериализации для графа объектов"> stackoverflow.com/questions/22590073/ - person Lex Hartman; 29.08.2016