Php Symfony2多对多关系更新
我有一个多对多关系,实际上是由第三个实体上的两个多对一组成Php Symfony2多对多关系更新,php,symfony,doctrine-orm,many-to-many,Php,Symfony,Doctrine Orm,Many To Many,我有一个多对多关系,实际上是由第三个实体上的两个多对一组成 域← 一对多→ 领地← 多对一→ 标签 我正在构建一个RESTAPI,我想通过特定的路由将域添加到标记中。当标签没有关联时,一切正常。 但是,当我尝试向标记添加新域时,如果标记已经作为一个(或多个)域存在,则会出现错误。 错误是 表单的视图数据应为scalar、array或\ArrayAccess的实例类型,但应为AppBundle\Entity\Domain类的实例。通过将“data\u class”选项设置为“AppBundle\E
域← 一对多→ 领地← 多对一→ 标签
我正在构建一个RESTAPI,我想通过特定的路由将域添加到标记中。当标签没有关联时,一切正常。
但是,当我尝试向标记添加新域时,如果标记已经作为一个(或多个)域存在,则会出现错误。
错误是
表单的视图数据应为scalar、array或\ArrayAccess的实例类型,但应为AppBundle\Entity\Domain类的实例。通过将“data\u class”选项设置为“AppBundle\Entity\Domain”,或添加一个视图转换器,将类AppBundle\Entity\Domain的实例转换为标量、数组或\ArrayAccess的实例,可以避免此错误。
以下是三个实体:
标签
领地
class DomainTag
{
…
/**
* @var Tag
*
* @ORM\ManyToOne(targetEntity="Tag", inversedBy="domainTags")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="tag_id", referencedColumnName="id")
* })
*/
private $tag;
/**
* @var Domain
*
* @ORM\ManyToOne(targetEntity="Domain", inversedBy="domainTags")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="domain_id", referencedColumnName="id")
* })
*/
private $domain;
…
}
领域
class Domain
{
…
/**
* @ORM\OneToMany(targetEntity="DomainTag", mappedBy="domain", cascade={"persist", "remove"})
*/
private $domainTags;
…
}
这是表格
class AddDomainTagFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('domainTags', 'collection', array(
'type' => new DomainTagFormType(),
'allow_add' => true,
))
;
}
// BC for SF < 2.7
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Tag',
'csrf_protection' => false,
));
}
public function getName()
{
return 'api_set_domaintag';
}
}
是否必须从标记中删除所有DomainTag并重新创建所有关联?或者有没有一种方法可以添加/删除域名标签
谢谢你你能不能也粘贴
DomainTagFormType
代码?我已经在第一个表单之后添加了它。你能不能也粘贴DomainTagFormType
代码?我已经在第一个表单之后添加了它
class AddDomainTagFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('domainTags', 'collection', array(
'type' => new DomainTagFormType(),
'allow_add' => true,
))
;
}
// BC for SF < 2.7
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Tag',
'csrf_protection' => false,
));
}
public function getName()
{
return 'api_set_domaintag';
}
}
class DomainTagFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('weight')
->add('domain', 'entity', array(
'class' => 'AppBundle:Domain',
'property' => 'id',
'multiple' => false,
'expanded' => true
))
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\DomainTag',
'csrf_protection' => false,
));
}
// BC for SF < 2.7
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$this->configureOptions($resolver);
}
public function getName()
{
return 'api_domaintag';
}
}
/**
* @Rest\Put("/{id}/domains", requirements={"id" = "\d+"})
* @Security("has_role('ROLE_SUPER_ADMIN')")
* @Rest\View
*/
public function setDomainAction(Request $request, $id)
{
$tagManager = $this->get('app.manager.tag');
$domainManager = $this->get('app.manager.domain');
$tag = $tagManager->find($id);
if (!$tag) {
return new Response('Tag not found', 404);
}
$form = $this->createForm(new AddDomainTagFormType(), $tag, array('method' => 'PUT'));
$form->handleRequest($request);
if ($form->isValid()) {
foreach ($tag->getDomainTags() as $dt) {
$dt->setTag($tag);
$tagManager->persist($dt);
}
$tagManager->flush($tag);
return new Response('', 204);
} else {
return $this->view($form, 400);
}
}