我使用的Symfony 2.1和條令2.Symfony的2 - 多個表單字段爲一個數據庫行
我負責的兩個主要實體:地點和特徵,他們之間的多對多關係。 數據庫中有很多功能,並按主題對它們進行分組,功能也與具有ManyToOne關係的FeatureCategory實體相關。
這裏的不同實體的代碼:
的廣場實體
namespace Mv\PlaceBundle\Entity;
…
/**
* Mv\PlaceBundle\Entity\Place
*
* @ORM\Table(name="place")
* @ORM\Entity(repositoryClass="Mv\PlaceBundle\Entity\Repository\PlaceRepository")
* @ORM\HasLifecycleCallbacks
*/
class Place
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string $name
*
* @ORM\Column(name="name", type="string", length=255, unique=true)
* @Assert\NotBlank
*/
private $name;
/**
* @ORM\ManyToMany(targetEntity="\Mv\MainBundle\Entity\Feature")
* @ORM\JoinTable(name="places_features",
* joinColumns={@ORM\JoinColumn(name="place_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="feature_id", referencedColumnName="id")}
*)
*/
private $features;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
* @return Place
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Add features
*
* @param \Mv\MainBundle\Entity\Feature $features
* @return Place
*/
public function addFeature(\Mv\MainBundle\Entity\Feature $features)
{
$this->features[] = $features;
echo 'Add "'.$features.'" - Total '.count($this->features).'<br />';
return $this;
}
/**
* Remove features
*
* @param \Mv\MainBundle\Entity\Feature $features
*/
public function removeFeature(\Mv\MainBundle\Entity\Feature $features)
{
$this->features->removeElement($features);
}
/**
* Get features
*
* @return Doctrine\Common\Collections\Collection
*/
public function getFeatures()
{
return $this->features;
}
public function __construct()
{
$this->features = new \Doctrine\Common\Collections\ArrayCollection();
}
的特點實體:
namespace Mv\MainBundle\Entity;
…
/**
* @ORM\Entity
* @ORM\Table(name="feature")
* @ORM\HasLifecycleCallbacks
*/
class Feature
{
use KrToolsTraits\PictureTrait;
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(name="label", type="string", length=255)
* @Assert\NotBlank()
*/
protected $label;
/**
* @ORM\ManyToOne(targetEntity="\Mv\MainBundle\Entity\FeatureCategory", inversedBy="features", cascade={"persist"})
* @ORM\JoinColumn(name="category_id", referencedColumnName="id")
*/
private $category;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set label
*
* @param string $label
* @return Feature
*/
public function setLabel($label)
{
$this->label = $label;
return $this;
}
/**
* Get label
*
* @return string
*/
public function getLabel()
{
return $this->label;
}
/**
* Set category
*
* @param Mv\MainBundle\Entity\FeatureCategory $category
* @return Feature
*/
public function setCategory(\Mv\MainBundle\Entity\FeatureCategory $category = null)
{
$this->category = $category;
return $this;
}
/**
* Get category
*
* @return Mv\MainBundle\Entity\FeatureCategory
*/
public function getCategory()
{
return $this->category;
}
}
的FeatureCategory實體:
namespace Mv\MainBundle\Entity;
...
/**
* @ORM\Entity
* @ORM\Table(name="feature_category")
*/
class FeatureCategory
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(name="code", type="string", length=255)
* @Assert\NotBlank()
*/
protected $code;
/**
* @ORM\Column(name="label", type="string", length=255)
* @Assert\NotBlank()
*/
protected $label;
/**
* @ORM\OneToMany(targetEntity="\Mv\MainBundle\Entity\Feature", mappedBy="category", cascade={"persist", "remove"}, orphanRemoval=true)
* @Assert\Valid()
*/
private $features;
public function __construct()
{
$this->features = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set code
*
* @param string $code
* @return Feature
*/
public function setCode($code)
{
$this->code = $code;
return $this;
}
/**
* Get code
*
* @return string
*/
public function getCode()
{
return $this->code;
}
/**
* Set label
*
* @param string $label
* @return Feature
*/
public function setLabel($label)
{
$this->label = $label;
return $this;
}
/**
* Get label
*
* @return string
*/
public function getLabel()
{
return $this->label;
}
/**
* Add features
*
* @param \Mv\MainBundle\Entity\Feature $features
*/
public function addFeatures(\Mv\MainBundle\Entity\Feature $features){
$features->setCategory($this);
$this->features[] = $features;
}
/**
* Get features
*
* @return Doctrine\Common\Collections\Collection
*/
public function getFeatures()
{
return $this->features;
}
/*
* Set features
*/
public function setFeatures(\Doctrine\Common\Collections\Collection $features)
{
foreach ($features as $feature)
{
$feature->setCategory($this);
}
$this->features = $features;
}
/**
* Remove features
*
* @param Mv\MainBundle\Entity\Feature $features
*/
public function removeFeature(\Mv\MainBundle\Entity\Feature $features)
{
$this->features->removeElement($features);
}
/**
* Add features
*
* @param Mv\MainBundle\Entity\Feature $features
* @return FeatureCategory
*/
public function addFeature(\Mv\MainBundle\Entity\Feature $features)
{
$features->setCategory($this);
$this->features[] = $features;
}
}
功能表已填充完畢,用戶將無法添加功能,只能在表單集合中選擇它們以將它們鏈接到「地點」。 (該功能實體目前僅與地點鏈接,但稍後將與我的應用程序中的其他實體相關,並將包含所有實體可用的所有功能)
在地方表單中,我需要顯示覆選框一個地方可用的功能,但我需要顯示他們按類別分組。 實施例:
訪問數(FeatureCategory - 代碼VIS):
- 免費(功能)
- 付費(功能)
口頭語(FeatureCategory - 代碼LAN):
- 英文(功能)
- 法語(功能)
- 西班牙語(功能)
我的想法
使用虛擬表單在我的PlaceType形式,像這樣:
$builder
->add('name')
->add('visit', new FeatureType('VIS'), array(
'data_class' => 'Mv\PlaceBundle\Entity\Place'
))
->add('language', new FeatureType('LAN'), array(
'data_class' => 'Mv\PlaceBundle\Entity\Place'
));
,並創建一個FeatureType虛擬表單,如下所示:
class FeatureType extends AbstractType
{
protected $codeCat;
public function __construct($codeCat)
{
$this->codeCat = $codeCat;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('features', 'entity', array(
'class' => 'MvMainBundle:Feature',
'query_builder' => function(EntityRepository $er)
{
return $er->createQueryBuilder('f')
->leftJoin('f.category', 'c')
->andWhere('c.code = :codeCat')
->setParameter('codeCat', $this->codeCat)
->orderBy('f.position', 'ASC');
},
'expanded' => true,
'multiple' => true
));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'virtual' => true
));
}
public function getName()
{
return 'features';
}
}
有了這個解決方案,我得到了我想要的,但綁定過程不會保留所有功能。它不是將它們分組,而是隻保留我並堅持最後一組「語言」,並刪除所有的上一個特徵數據。爲了看到它的作用,如果我檢查了5個複選框,它可以很好地進入Place-> addFeature()函數5次,但函數arrayCollection的長度是連續的:1,2,1,2,3。
任何想法如何以另一種方式做到這一點?如果我需要改變模型,我仍然可以做到。 什麼是最好的方式,可重複使用我的未來其他實體也與功能相關,來處理這個問題?
謝謝你們。