Symfony ManyToMany 关系部分工作
Symfony ManyToMany relationship working partially
我遇到了一个理论上听起来很简单的问题,但在 Symfony 中我无法实现它,所以我希望这里的任何人都可以将我推向正确的方向。
我将首先解释我正在尝试做什么,并让您知道我在多大程度上试图实现这一目标。仅供参考,我使用的是 Symfony 3.0
我想做什么
- 我有两个实体 'Post' 和 'Category' 并且它们是链接在一起的
在 ManytoMany 双向关系中一起。
- 当我创建一个新的 post 时,我想为其分配一个类别,该类别应该是复选框并与类别实体链接
- 保存 post 后,当我对其进行编辑时,类别复选框应显示为 selected(那些分配给 post 的类别)
到目前为止我做了什么
实体已经链接并且关系似乎工作正常,因为当我保存 post 它被保存并且类别的连接 table 和 posts 被更新为post id 和类别 id。如果我 select 多个类别,它们也会在连接 table.
中保存
我卡在什么地方了
当我编辑 post 时,post 数据显示正常,但类别复选框未显示为 selected,这就是我需要您帮助的地方。
我是如何创建表格的。
我不确定这是否是正确的方法,但它似乎有效,所以如果我在某个地方错了并且没有按照 symfony 的方式正确地做,请纠正我。
这是来自 post.orm.yml
的 manyTomany
manyToMany:
categories:
targetEntity: MyBundle\Entity\Category
inversedBy: posts
joinTable:
name: posts_categories
joinColumns:
post_id:
referencedColumnName: id
inverseJoinColumns:
category_id:
referencedColumnName: id
cascade: ["persist"]
这是来自 category.orm.yml
的 manyTomany
manyToMany:
posts:
targetEntity: MyBundle\Entity\Post
mappedBy: categories
joinTable:
name: posts_categories
joinColumns:
post_id:
referencedColumnName: id
inverseJoinColumns:
category_id:
referencedColumnName: id
CategoryType
直截了当
class CategoryType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name');
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'MyBundle\Entity\Category'
));
}
}
这是 PostType
,这是我怀疑我是否做对的地方。
class PostType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title')
->add('description')
->add('category', EntityType::class, array(
'class' => 'MyBundle\Entity\Category',
'choice_label' => 'name',
'multiple' => true,
'expanded' => true,
'by_reference' => false,
))
->add('categories', CollectionType::class, array(
'entry_type' => CategoryType::class,
'by_reference' => false
));;
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'MyBundle\Entity\Post'
));
}
}
为了显示已创建的类别,我在 Post
实体中创建了一个新的 属性,名称为 Category
,在 PostType
中拉动类别来自 Category
实体。
然后还有 categories
CollectionType。提交表单后,我使用循环在连接 table 中添加类别。
$catagories = $form->get('category')->getData();
foreach ($catagories as $cat) {
$post->getCategories()->add($cat);
}
这样做确实会在加入 table 中保存信息,但是当我编辑它时,复选框不会显示为 selected。
我注意到的另一件奇怪的事情是,如果我从 PostType
中删除 ->add('categories', CollectionType::class
,我会收到以下错误,这真的很奇怪,因为这些值不存在于 table 中,所以我不知道为什么它说它们是重复的
posts_categories (post_id, category_id) VALUES (?, ?)' with params [30, 1]: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '30-1' for key 'PRIMARY'
如果有人能告诉我我做错了什么,我将不胜感激。
更新:只需添加一张图片即可显示 post_id 和 category_id 正在保存在加入 table 中
好的,这就是我的发现。
如果关系设置为 manyToMany,只要 multiple
和 expanded
设置为 true
,EntityType
就会呈现为复选框。所以我所要做的就是
- 摆脱我在控制器中使用的 foreach 循环
- 清理
PostType
如下
class PostType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title')
->add('description')
->add('categories', EntityType::class, array(
'class' => 'MyBundle\Entity\Category',
'choice_label' => 'name',
'multiple' => true,
'expanded' => true,
'by_reference' => false,
));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'MyBundle\Entity\Post'
));
}
}
就是这样,现在我仍然可以在连接 table 中保存 category_id
和 post_id
,并且在编辑时我可以看到默认选择的类别。
我遇到了一个理论上听起来很简单的问题,但在 Symfony 中我无法实现它,所以我希望这里的任何人都可以将我推向正确的方向。
我将首先解释我正在尝试做什么,并让您知道我在多大程度上试图实现这一目标。仅供参考,我使用的是 Symfony 3.0
我想做什么
- 我有两个实体 'Post' 和 'Category' 并且它们是链接在一起的 在 ManytoMany 双向关系中一起。
- 当我创建一个新的 post 时,我想为其分配一个类别,该类别应该是复选框并与类别实体链接
- 保存 post 后,当我对其进行编辑时,类别复选框应显示为 selected(那些分配给 post 的类别)
到目前为止我做了什么
实体已经链接并且关系似乎工作正常,因为当我保存 post 它被保存并且类别的连接 table 和 posts 被更新为post id 和类别 id。如果我 select 多个类别,它们也会在连接 table.
中保存我卡在什么地方了
当我编辑 post 时,post 数据显示正常,但类别复选框未显示为 selected,这就是我需要您帮助的地方。
我是如何创建表格的。
我不确定这是否是正确的方法,但它似乎有效,所以如果我在某个地方错了并且没有按照 symfony 的方式正确地做,请纠正我。
这是来自 post.orm.yml
manyToMany:
categories:
targetEntity: MyBundle\Entity\Category
inversedBy: posts
joinTable:
name: posts_categories
joinColumns:
post_id:
referencedColumnName: id
inverseJoinColumns:
category_id:
referencedColumnName: id
cascade: ["persist"]
这是来自 category.orm.yml
manyToMany:
posts:
targetEntity: MyBundle\Entity\Post
mappedBy: categories
joinTable:
name: posts_categories
joinColumns:
post_id:
referencedColumnName: id
inverseJoinColumns:
category_id:
referencedColumnName: id
CategoryType
直截了当
class CategoryType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name');
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'MyBundle\Entity\Category'
));
}
}
这是 PostType
,这是我怀疑我是否做对的地方。
class PostType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title')
->add('description')
->add('category', EntityType::class, array(
'class' => 'MyBundle\Entity\Category',
'choice_label' => 'name',
'multiple' => true,
'expanded' => true,
'by_reference' => false,
))
->add('categories', CollectionType::class, array(
'entry_type' => CategoryType::class,
'by_reference' => false
));;
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'MyBundle\Entity\Post'
));
}
}
为了显示已创建的类别,我在 Post
实体中创建了一个新的 属性,名称为 Category
,在 PostType
中拉动类别来自 Category
实体。
然后还有 categories
CollectionType。提交表单后,我使用循环在连接 table 中添加类别。
$catagories = $form->get('category')->getData();
foreach ($catagories as $cat) {
$post->getCategories()->add($cat);
}
这样做确实会在加入 table 中保存信息,但是当我编辑它时,复选框不会显示为 selected。
我注意到的另一件奇怪的事情是,如果我从 PostType
中删除 ->add('categories', CollectionType::class
,我会收到以下错误,这真的很奇怪,因为这些值不存在于 table 中,所以我不知道为什么它说它们是重复的
posts_categories (post_id, category_id) VALUES (?, ?)' with params [30, 1]: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '30-1' for key 'PRIMARY'
如果有人能告诉我我做错了什么,我将不胜感激。
更新:只需添加一张图片即可显示 post_id 和 category_id 正在保存在加入 table 中
好的,这就是我的发现。
如果关系设置为 manyToMany,只要 multiple
和 expanded
设置为 true
,EntityType
就会呈现为复选框。所以我所要做的就是
- 摆脱我在控制器中使用的 foreach 循环
- 清理
PostType
如下
class PostType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('title') ->add('description') ->add('categories', EntityType::class, array( 'class' => 'MyBundle\Entity\Category', 'choice_label' => 'name', 'multiple' => true, 'expanded' => true, 'by_reference' => false, )); } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( 'data_class' => 'MyBundle\Entity\Post' )); } }
就是这样,现在我仍然可以在连接 table 中保存 category_id
和 post_id
,并且在编辑时我可以看到默认选择的类别。