TangoMan Relationship Bundle provides magic methods for OneToOne, OneToMany, ManyToOne, ManyToMany, relationships.
Open a command console, enter your project directory and execute the following command to download the latest stable version of this bundle:
$ composer require tangoman/relationship-bundleThis command requires you to have Composer installed globally, as explained in the installation chapter of the Composer documentation.
Then, enable the bundle by adding it to the list of registered bundles
in the app/AppKernel.php file of your project:
<?php
// app/AppKernel.php
// ...
class AppKernel extends Kernel
{
// ...
public function registerBundles()
{
$bundles = array(
// ...
new TangoMan\FrontBundle\TangoManRelationshipBundle(),
);
// ...
}
}Use TangoMan\RelationshipBundle\Traits\HasRelationships trait inside your entities,
and define properties with appropriate doctrine annotations.
Open a command console, enter your project directory and execute the following command to update your database schema:
$ php bin/console schema:update- Both entities must use
HasRelationshipstrait. - Both entities must define properties with appropriate doctrine annotations.
cascade={"persist"}annotation is MANDATORY (will allow bidirectional linking between entities).@methodannotation will allow for correct autocomplete in your IDE (optional).- NOTE:
inversedByis always on the owning side of the relationship (but I believe you know that already.)
cascade={"remove"}will avoid orphanItemonOwnerdeletion (optional).
<?php
// src\AppBundle\Entity\Owner.php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use TangoMan\RelationshipBundle\Traits\HasRelationships;
/**
* Class Owner
* @ORM\Table(name="owner")
* @ORM\Entity(repositoryClass="AppBundle\Repository\OwnerRepository")
*
* @package AppBundle\Entity
*
* @method $this setItem(Item $item)
* @method Item getItems()
*/
class Owner
{
use HasRelationships;
// ...
/**
* @var Item
* @ORM\OneToOne(targetEntity="AppBundle\Entity\Item", inversedBy="owner", cascade={"persist", "remove"})
*/
private $item;
// ...<?php
// src\AppBundle\Entity\Item.php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use TangoMan\RelationshipBundle\Traits\HasRelationships;
/**
* Class Item
* @ORM\Table(name="item")
* @ORM\Entity(repositoryClass="AppBundle\Repository\ItemRepository")
*
* @package AppBundle\Entity
*
* @method $this setOwner(Owner $owner)
* @method Owner getOwner()
*/
class Item
{
use HasRelationships;
// ...
/**
* @var Owner
* @ORM\OneToOne(targetEntity="AppBundle\Entity\Owner", mappedBy="item", cascade={"persist"})
*/
private $owner;
// ...- Property must own
@var ArrayCollection - Property name MUST use plural form (as it represents several entities)
@ORM\OrderBy({"name"="ASC"})will allow to define custom orderBy when fetchingitems(optional).
<?php
// src\AppBundle\Entity\Owner.php
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use TangoMan\RelationshipBundle\Traits\HasRelationships;
/**
* Class Owner
* @ORM\Table(name="owner")
* @ORM\Entity(repositoryClass="AppBundle\Repository\OwnerRepository")
*
* @package AppBundle\Entity
*
* @method $this setItems(Item[] $items)
* @method Item getItems()
*/
class Owner
{
use HasRelationships;
// ...
/**
* @var ArrayCollection|Item[]
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Item", inversedBy="owners", cascade={"persist", "remove"})
* @ORM\OrderBy({"name"="ASC"})
*/
private $items;
// ...<?php
// src\AppBundle\Entity\Item.php
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use TangoMan\RelationshipBundle\Traits\HasRelationships;
/**
* Class Item
* @ORM\Table(name="item")
* @ORM\Entity(repositoryClass="AppBundle\Repository\ItemRepository")
*
* @package AppBundle\Entity
*
* @method $this setOwners(Owner[] $owners)
* @method Owner getOwners()
*/
class Item
{
use HasRelationships;
// ...
/**
* @var ArrayCollection|Owner[]
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Owner", mappedBy="items", cascade={"persist"})
* @ORM\OrderBy({"name"="ASC"})
*/
private $owners;
// ...Constructors MUST initialize properties with ArrayCollection
<?php
// src\AppBundle\Entity\Owner.php
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use TangoMan\RelationshipBundle\Traits\HasRelationships;
// ...
/**
* Owner constructor.
*/
public function __construct()
{
// ...
$this->Items = new ArrayCollection();
}Your formTypes elements from the INVERSE side of relationships MUST own 'by_reference' => false, attribute
to force use of appropriate setters and getters (i.e. add and remove methods).
<?php
// src\AppBundle\Form\ItemType.php
// ...
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
// ...
->add(
'owner',
EntityType::class,
[
'label' => 'Owner',
'placeholder' => 'Select owner',
'class' => 'AppBundle:Owner',
'by_reference' => false,
'multiple' => true,
'expanded' => false,
'required' => false,
'query_builder' => function (EntityRepository $em) {
return $em->createQueryBuilder('o')
->orderBy('o.name');
},
]
);
}If you find any bug please report here : Issues
Copyright (c) 2018 Matthias Morin
Distributed under the MIT license.
If you like TangoMan Relationship Bundle please star! And follow me on GitHub: TangoMan75 ... And check my other cool projects.