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-bundle
This 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
HasRelationships
trait. - Both entities must define properties with appropriate doctrine annotations.
cascade={"persist"}
annotation is MANDATORY (will allow bidirectional linking between entities).@method
annotation will allow for correct autocomplete in your IDE (optional).- NOTE:
inversedBy
is always on the owning side of the relationship (but I believe you know that already.)
cascade={"remove"}
will avoid orphanItem
onOwner
deletion (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.