Один ко многим отношениям и добавить / редактировать форму в сонатаадмин и симфонии2

StackOverflow https://stackoverflow.com//questions/24010849

Вопрос

У меня есть простое приложение Symfony2 с двумя объектами: муниципалитетом и POI. Существует соотношение «однозначное» между муниципалитетом и POI (I.E: ZERO или более POIS, размещенные в одном муниципалитете), поэтому файлы сущности такие:

POC \ POCBUNDLE \ ENTITY \ MUNECIDALION.PHP

<?php

// Poc\PocBundle\Entity\Municipality.php

namespace Poc\PocBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Municipality
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Poc\PocBundle\Entity\MunicipalityRepository")
 */
class Municipality
{
    /**
     * @ORM\OneToMany(targetEntity="Poi", mappedBy="municipality")
     */
    protected $pois;

    public function __construct()
    {
        $this->pois = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

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


    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Municipality
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Add pois
     *
     * @param \Poc\PocBundle\Entity\Poi $pois
     * @return Municipality
     */
    public function addPois(\Poc\PocBundle\Entity\Poi $pois)
    {
        $this->pois[] = $pois;

        return $this;
    }

    /**
     * Remove pois
     *
     * @param \Poc\PocBundle\Entity\Poi $pois
     */
    public function removePois(\Poc\PocBundle\Entity\Poi $pois)
    {
        $this->pois->removeElement($pois);
    }

    /**
     * Get pois
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getPois()
    {
        return $this->pois;
    }

    public function __toString()
    {
        return $this->name;
    }
}
.

POC \ PocBundle \ Entity \ Poi.php

<?php

// Poc\PocBundle\Entity\Poi.php

namespace Poc\PocBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Poi
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Poc\PocBundle\Entity\PoiRepository")
 */
class Poi
{
    /**
     * @ORM\ManyToOne(targetEntity="Municipality", inversedBy="pois")
     * @ORM\JoinColumn(name="municipality_id", referencedColumnName="id")
     */
    protected $municipality;

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

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


    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Poi
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set municipality
     *
     * @param \Poc\PocBundle\Entity\Municipality $municipality
     * @return Poi
     */
    public function setMunicipality(\Poc\PocBundle\Entity\Municipality $municipality = null)
    {
        $this->municipality = $municipality;

        return $this;
    }

    /**
     * Get municipality
     *
     * @return \Poc\PocBundle\Entity\Municipality 
     */
    public function getMunicipality()
    {
        return $this->municipality;
    }

    public function __toString()
    {
        return $this->name;
    }
}
.

На данный момент я хочу управлять однозначным соотношением между муниципалитетом и их POI из муниципалитета Add / редактирование формы в Admin Sonata.

Я следовал инструкциям, объясненным в http://sonata-project.org/bundles/doctrine-orm-admin/master/doc/reference/form_field_definition.html#advanced-Usage-one-one-mo-many Так что файл класса муниципалитетадмина:

poC / pocbundle / admin / muticalityadmin.php

<?php
namespace Poc\PocBundle\Admin;

use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Show\ShowMapper;

class MunicipalityAdmin extends Admin
{
    protected function configureListFields(ListMapper $listMapper)
    {
        $listMapper
            ->addIdentifier('name')
            ->add('_action', 'actions', array(
                'actions' => array(
                    'show' => array(),
                    'edit' => array(),
                )
            ))
        ;
    }
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('name')
            ->add('pois', 'sonata_type_collection', array(), array(
                'edit' => 'inline',
                'inline' => 'table',
                'sortable'  => 'position'
            ))
    ;
    }
}
.

Форма, которую я пытаюсь получить, это форма добавления / редактирования, где я могу определить de имя муниципалитета, и добавить / удалить связанные pois из сущности POI, но то, что я действительно получаю, это форма, где я могу определить имя муниципалитета и управление сущностью POI в виду субформируют.

Эта скриншот описывает результат -> http://i.imgur.com/nm1ywwh.png

Я имею в виду, таким образом, я могу добавить новые POI и отношения с любым муниципалитетом (т. Е. Лос-Анджелес), но то, что я пытаюсь получить, это список AL POI, которые связаны с этим муниципалитетом и возможностью к:

    .
  • Добавить новые отношения (то есть: ассоциировать сиротю подобную статую свободы в этом муниципалитете (Нью-Йорк)).
  • Удалить существующие соотношения (I.E: Удалить неправильное отношение, например, «Концертный зал Walt Disney Disney» в Нью-Йорке)

Я видел способ управлять этим в обратном пути, выбирая муниципалитет, связанный с каждым POI в форме POI Add / Edit (многие к одному), но мне интересно, есть ли способ управлять этим отношения в другом объекте.

Могу ли я сделать это в сонатаадмине? Любая подсказка?

Обновление: решается пользовательский интерфейс и добавление POI, но не удаление

У меня есть путь, чтобы показать виджет, который я ищу, определив форму таким образом:

protected function configureFormFields(FormMapper $formMapper)
{
    $formMapper
        ->add('name')
        ->add('pois', null, array(), array(
            'edit' => 'inline',
            'inline' => 'table',
            'sortable'  => 'position'
        ))
;
}
.

Что я сделал, это изменить «sonata_type_collection» для нулевого значения. Теперь я получаю форму, как этот скриншот -> Правильная форма GUI

... что как просто поведение, которое я хочу.

Первоначально добавления в этом виджете (I.E: добавьте новых POO в муниципалитет), не сохранился. Благодаря комментарию Radomir Wojtera, я понял, что были методы, не реализованные в моем классе сущности муниципалитета (SetPois, AddPoi и RemovePoi).

Я добавил эти методы ...

public function setPois($pois)
{
    if (count($pois) > 0) {
        foreach ($pois as $i) {
            $this->addPoi($i);
        }
    }

    return $this;
}

public function addPoi(\Poc\PocBundle\Entity\Poi $poi)
{
    $poi->setMunicipality($this);
    $this->pois->add($poi);
}

public function removePoi(\Poc\PocBundle\Entity\Poi $poi)
{
    $this->pois->removeElement($poi);
}
.

... И теперь я могу схватить новые POI для муниципалитета, но когда я удаляю некоторые POI, они не разобрались. Так что я могу добавить отношения, но не удалять.

Это было полезно?

Решение

Наконец я могу решить вторую проблему (удаление POI из муниципалитета не работал), установив orphanremoval= true в конфигурации объекта

class Municipality
{
    /**
     * @ORM\OneToMany(targetEntity="Poi", mappedBy="municipality", cascade={"persist"}, orphanRemoval=true))
     */
    protected $pois;
...
.

Первый вопрос решается, как прокомментировано в обновлении вопроса.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top