SonataAdminとsymfony2で、多くの関係と編集/編集フォーム
-
21-12-2019 - |
質問
私は2つのエンティティを持つ単純なsymfony2アプリケーションを持っています:自治体とPOI。地方自治体とPOI(すなわち、1つの自治体に配置されたPOI)の間に「1対多」という関係があるため、エンティティファイルは次のようになります。
Poc \ Pocbundle \ Entity \ Municipality.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;
}
}
.
現時点では、Sonata管理者の自治体とそのPOIの間の一対の関係を管理したいです。
私は
Poc / Pocbundle / Admin / MunicipalityAdmin.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'
))
;
}
}
.
私がgetを取得しようとしているフォームは、私が自治体の名前を定義し、関連するPOIをPOIエンティティから追加/削除できる追加/編集フォームですが、私が実際にGETを取得するものは、名前を定義できる形式です。自治体の一種のサブフォームでPOIエンティティを管理します。
このスクリーンシュートは結果を記述します - > http://i.imgur.com/nm1ywwh.png
このように、私は新しいPOIと関係を自治体とともに追加することができます(つまり、ロサンゼルス)が、私が得ることを試みようとしているものは、この自治体と可動性に関連するAL POIのリストです。
- 新たな関係を追加する(すなわち、この自治体の静音像のようなorphan Poiの歴史(ニューヨーク))。
- 既存の関係を取り除く(I.E:ニューヨークのWalt Disneyコンサートホールのような誤った関係を削除)
これを逆方向に管理する方法を見て、POI追加/編集フォーム(多対1)の各POIに関連する自治体を選択しましたが、これを管理する方法があるのは不思議です。他のエンティティの関係
SonataAdminでこれをやることができますか?任意の手がかり?
更新:UIとPOIを追加したが、
を削除しないこのようにフォームを定義することによって、私が探しているウィジェットを見せる方法を持っています:
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('name')
->add('pois', null, array(), array(
'edit' => 'inline',
'inline' => 'table',
'sortable' => 'position'
))
;
}
.
私がしたことは、NULL値に対して 'sonata_type_collection'を変更することです。今、このスクリーンショットのようなフォームを入手します - >
...それは私が欲しい行動だけです。
最初にこのウィジェットの追加(すなわち、自治体に新しいPOIを追加する)は、持続しませんでした。 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を取り除くとき、彼らは解決しませんでした。だから私は関係を追加することができますが、削除されません。
解決
最後に私はorphanremoval= trueをエンティティ構成で設定することで、2番目の問題を解決できませんでした(自治体からのPOIの削除はうまくいませんでした)
class Municipality
{
/**
* @ORM\OneToMany(targetEntity="Poi", mappedBy="municipality", cascade={"persist"}, orphanRemoval=true))
*/
protected $pois;
...
.
最初の問題は、質問更新にコメントしているので解決されています。