Assign many items to one category - OneToMany Relation
和
Symfony form not saving entity with ManyToMany relation
根据上面的两个问题,我有一个列表,其中包含许多项目的复选框。因此,拥有2个路由/方法没有任何意义:一个用于分配,另一个用于删除项目。为了使其在逻辑上正确,分配项目和删除项目必须在一个方法中 - 此方法仅用于分配而不是用于移除一个或多个项目。在实际的应用程序中,在一个步骤中分配和删除项目是唯一有意义的方法(因为复选框)。
/**
* Assign items to category and remove items from the list
*
* @Route("/{id}/assign", name="category_assign")
* @Template("CheckoutItemBundle:Category:assign.html.twig")
* @param Request $request
* @param $id
* @return array|\Symfony\Component\HttpFoundation\RedirectResponse
*/
public function assignAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('CheckoutItemBundle:Category')->find($id);
if (!$entity)
{
throw $this->createNotFoundException('Unable to find Category entity.');
}
$tokenStorage = $this->container->get('security.token_storage');
$form = $this->createForm(new CategoryItemType($tokenStorage), $entity, array(
'method' => 'POST',
));
$form->add('submit', 'submit', array('label' => 'Save'));
$form->handleRequest($request);
if ($form->isValid())
{
$data = $form->getData();
foreach($data->getItems() as $item)
{
$item->setCategory($entity);
$em->persist($item);
}
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('category'));
}
return array(
'entity' => $entity,
'form' => $form->createView()
);
}
形式:
<?php
namespace Checkout\Bundle\ItemBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Doctrine\ORM\EntityRepository;
class CategoryItemType extends AbstractType
{
private $tokenStorage;
public function __construct(TokenStorageInterface $tokenStorage)
{
$this->tokenStorage = $tokenStorage;
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$currentUser = $this->tokenStorage->getToken()->getUser();
$builder
->add('items', 'entity', array(
'label' => 'Items',
'required' => false,
'class' => 'CheckoutItemBundle:Item',
'property' => 'name',
'expanded' => true,
'multiple' => true,
'query_builder' => function (EntityRepository $er) use ($currentUser) {
return $er->createQueryBuilder('c')
->where('c.user = :user')
->setParameter('user', $currentUser);
},
))
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Checkout\Bundle\ItemBundle\Entity\Category'
));
}
/**
* @return string
*/
public function getName()
{
return 'checkout_bundle_itembundle_category_items';
}
}
实体类别:
class Category
{
/**
* @var integer
*
* @ORM\Column(type="guid")
* @ORM\Id
* @ORM\GeneratedValue(strategy="UUID")
*/
private $id;
/**
* @ORM\OneToMany(targetEntity="Checkout\Bundle\ItemBundle\Entity\Item", mappedBy="category", cascade={"persist", "remove"})
**/
private $items;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* @var string
*
* @ORM\Column(name="description", type="text")
*/
private $description;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\User")
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
**/
private $user;
/**
* Get id
*
* @return integer
*/
这里有完整的一个:http://laravel.io/bin/bEEr5(只需要很长时间,将其粘贴到此处。)
实体项目:
class Item
{
/**
* @var integer
*
* @ORM\Column(type="guid")
* @ORM\Id
* @ORM\GeneratedValue(strategy="UUID")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="description", type="text", nullable=true)
*/
private $description = null;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* @ORM\OneToMany(targetEntity="Checkout\Bundle\ItemBundle\Entity\ItemCharakter", mappedBy="item", cascade={"persist", "remove"})
**/
private $itemCharakters;
/**
* @ORM\ManyToOne(targetEntity="Checkout\Bundle\ItemBundle\Entity\Category", inversedBy="items")
* @ORM\JoinColumn(name="category_id", referencedColumnName="id")
**/
private $category;
/**
* @ORM\ManyToMany(targetEntity="Checkout\Bundle\ItemBundle\Entity\Tax", inversedBy="items")
* @ORM\JoinTable(name="Items_Taxes")
*/
private $taxes;
/**
* @ORM\ManyToMany(targetEntity="Checkout\Bundle\ItemBundle\Entity\Modifier", inversedBy="items")
* @ORM\JoinTable(name="Items_Modifiers")
*/
private $modifiers;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\User")
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
**/
private $user;
/**
* @var \DateTime $created_at
*
* @Gedmo\Timestampable(on="create")
* @ORM\Column(type="datetime")
*/
private $created_at;
/**
* @var \DateTime $updated_at
*
* @Gedmo\Timestampable(on="update")
* @ORM\Column(type="datetime")
*/
private $updated_at;
完整实体:http://laravel.io/bin/XyyxB
第一种情况:
Assign Items to Category:
[ ] Item 1
[ ] Item 2
指定所有====&gt;
Assign Items to Category:
[X] Item 1
[X] Item 2
第二
Assign Items to Category:
[ ] Item 1 // Remove this item 1, after it was assign
[X] Item 2 // Stay assigned
我不是在这里拥有的。我正在使用Symfony 2.6.7。在这个例子中,它是一个OneToMany关系,但在将来我也需要它为ManytoMany Relation。
任何想法,OneToMany和ManyToMany如何才能实现这一点,当时我不是在拥有这一方面? : - )
我也按照本指南添加项目部分:http://symfony.com/doc/current/book/doctrine.html#entity-relationships-associations - 可能有助于澄清。