在网上搜索了很长时间后,我决定自己写我的第一篇文章。我希望我用正确的方法。
这是我的问题。我在我的项目中使用symfony 2.1。我必须处理两个对象之间的双向多对多关系。我已经创建了两个实体,完成了映射,完成了控制器,模板和formBuilder。我设法持久化这两个实体。对于一个实体,我可以保留这个实体以及与另一个实体的关系。但是对于另一个实体,我只能保存这个实体。与其他实体的关系不持续
以下是两个实体的摘录:
class EntrainementCategorie{
{...}
/** @ORMManyToMany(targetEntity="EntrainementType", mappedBy="categories", cascade="persist") */
protected $types;
}
这是第二个实体:
class EntrainementType{
{...}
/**
* @ORMManyToMany(targetEntity="EntrainementCategorie",inversedBy="types", cascade="persist")
* @ORMJoinTable(name="mottet_entrainement_types_categories",
* joinColumns={@ORMJoinColumn(name="idType", referencedColumnName="id")},
* inverseJoinColumns={@ORMJoinColumn(name="idCategorie", referencedColumnName="id")})
*/
protected $categories;
}
所以你可以看到,在类别和类型之间有一个双向的多对多关系。
控制器如下:
class EntrainementCategorieController extends GenericController{
{...}
public function creerAction(Request $request){
return $this->creerActionGeneric($request,new Categorie(),new CategorieType());
}
}
第二个:
class EntrainementTypeController extends GenericController{
{...}
public function creerAction(Request $request){
return $this->creerActionGeneric($request,new Type(),new TypeType());
}
}
这里是GenericController
class GenericController extends Controller{
{...}
protected function creerActionGeneric(Request $request,$object,$objectType){
$form = $this->createForm($objectType,$object);
$isThereProblem = false;
if ($request->isMethod('POST')) {
$isThereProblem = true;
$form->bind($request);
if ($form->isValid()) {
$this->getEntityManager()->persist($object);
$this->getEntityManager()->flush();
$this->get('session')->getFlashBag()->add('information', $this->FORM_SUCCESS_MESSAGE);
$isThereProblem = false;
}
}
if ($isThereProblem){
$this->get('session')->getFlashBag()->add('error', $this->FORM_ERROR_MESSAGE);
}
return $this->render($this->BUNDLE.':'.$this->ENTITY.':'.$this->CREATE_TEMPLATE, array('form' => $form->createView()));
}
}
下面是formBuilder:
class EntrainementCategorieType extends AbstractType{
{...}
public function buildForm(FormBuilderInterface $builder, array $options){
$builder->add('label','text')
->add('types','entity',array(
'class' => 'KarateEntrainementBundle:EntrainementType',
'property' => 'label',
'multiple' => true,
'expanded' => true));
}
}
第二个:
class EntrainementTypeType extends AbstractType{
{...}
public function buildForm(FormBuilderInterface $builder, array $options){
$builder->add('label','text')
->add('categories','entity',array(
'class' => 'KarateEntrainementBundle:EntrainementCategorie',
'property' => 'label',
'multiple' => true,
'expanded' => true));
}
}
因此,当我填写EntrainementType表单时,类型及其与类别的关系都将被持久化。但是当我填写EntrainementCategory表单时,只有类别被持久化,而不是它与类型的关系。
有谁知道我做错了什么吗?
希望我已经说清楚了。谢谢你的帮助!
我终于做到了。我不能在那个上使用creerActionGeneric。我必须显式设置类别和每种类型之间的关联:
$form->bind($request);
if ($form->isValid()) {
$this->getEntityManager()->persist($categorie);
foreach($categorie->getTypes() as $type){
$type->addCategorie($categorie);
$this->getEntityManager()->persist($type);
}
$this->getEntityManager()->flush();
}
这工作得很好。但我不知道为什么在另一个方向上,当我坚持从类型,我不需要这样做吗??oO
有一种更好的方法可以通过原则配置关系。Doctrine允许您指定引用关系的连接表和列。
在决定深入阅读之前,我实际上是偶然发现了这个答案,因为这似乎不合适……这是正确的方式创建这样的关系(在html中,因为这是我喜欢的),并且显然与我的实体(提要可以拥有/属于许多列表,列表可以拥有/属于许多提要)
输入配置:
manyToMany:
providerLists:
targetEntity: ProviderList
joinTable:
name: providerlist_feed
joinColumns:
feed_id:
referencedColumnName: id
inverseJoinColumns:
providerlist_id:
referencedColumnName: id
list的配置
manyToMany:
feeds:
targetEntity: Feed
joinTable:
name: providerlist_feed
joinColumns:
providerlist_id:
referencedColumnName: id
inverseJoinColumns:
feed_id:
referencedColumnName: id
这样两个实体现在都拥有对方,并且都将以相同的方式保存:)