I have a problem with Symfony3/doctrine2 and many-to-many with extra columns. I just start to develop with it
Yes, I see the post : Doctrine2: Best way to handle many-to-many with extra columns in reference table But honestly, I don't understand why it's not working with my code...
I'm stuck since 2 days, looking on Google (he's not my friend), reading documentations... my brain doesn't understand...
Please, help me to understand why.
Problem
I have member and address entities. I would like to have all addresses by member OR all members by address. So, ManyToMany in Doctrine.
On my join Table, I need to have an extra column favorite_address
So, I need to have 3 entities : Member, Address, MemberAddress
Entity Member :
class Member implements AdvancedUserInterface
{
....
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Member\MemberAddress", mappedBy="member", cascade={"all"})
* @ORM\JoinTable(name="member_address",
* joinColumns={@ORM\JoinColumn(name="member_id", referencedColumnName="id")})
*/
private $addresses;
....
public function __construct(){
$this->addresses = new ArrayCollection();
}
/**
* Add an address
* @param Address $address
*/
public function addAddress(\AppBundle\Entity\Address\Address $address)
{
// Ici, on utilise l'ArrayCollection vraiment comme un tableau
$this->addresses[] = $address;
}
/**
* Remove an address
* @param Address $address
*/
public function removeAddress(\AppBundle\Entity\Address\Address $address)
{
// Ici on utilise une méthode de l'ArrayCollection, pour supprimer la catégorie en argument
$this->addresses->removeElement($address);
}
/**
* Get all addresses
* @return ArrayCollection
*/
public function getAddresses()
{
return $this->addresses;
}
Entity Address :
class Address
{
....
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Member\MemberAddress", mappedBy="address", cascade={"all"})
* @ORM\JoinTable(name="member_address",
* joinColumns={@ORM\JoinColumn(name="address_id", referencedColumnName="id")})
*/
private $members;
....
/**
* Add a member
* @param Member $member
*/
public function addMember(\AppBundle\Entity\Member\Member $member)
{
// Ici, on utilise l'ArrayCollection vraiment comme un tableau
$this->members[] = $member;
}
/**
* Remove a member
* @param Member $member
*/
public function removeMember(\AppBundle\Entity\Member\Member $member)
{
// Ici on utilise une méthode de l'ArrayCollection, pour supprimer la catégorie en argument
$this->members->removeElement($member);
}
/**
* Get all members
* @return ArrayCollection
*/
public function getMembers()
{
return $this->members;
}
And the last Entity : MemberAddressReference
class MemberAddress
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/** @ORM\ManyToOne(targetEntity="AppBundle\Entity\Member\Member", inversedBy="addresses")
* @ORM\JoinColumn(name="member_id", referencedColumnName="id")
*/
protected $member;
/** @ORM\ManyToOne(targetEntity="AppBundle\Entity\Address\Address", inversedBy="members")
* @ORM\JoinColumn(name="address_id", referencedColumnName="id")
*/
protected $address;
/** @ORM\Column(type="boolean") */
protected $isFavorite;
To finish, the controller
class MemberAddressController extends Controller
{
public function createAction(Request $request){
....
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$currentDate = new \DateTime("now");
$em = $this->getDoctrine()->getManager();
$address = new Address();
$memberAddress = new MemberAddress();
$address->setType($form['type']->getData());
$address->setCreated($currentDate);
$address->setModified($currentDate);
$memberAddress->setMember($member);
$memberAddress->setAddress($address);
$memberAddress->setFavorite(1);
$em->persist($member);
$em->persist($address);
$em->persist($memberAddress);
$member->addAddress($address);
$em->flush();
dump($member);
die();
}
So, what's wrong
I get this error :
Expected value of type "Doctrine\Common\Collections\Collection|array" for association field "AppBundle\Entity\Member\Member#$addresses", got "AppBundle\Entity\Address\Address" instead.
Yup, type is not good, I understand, but why he's not good ?
public function addAddress(\AppBundle\Entity\Address\Address $address)
{
// Ici, on utilise l'ArrayCollection vraiment comme un tableau
$this->addresses[] = $address;
}
addAddress take Address object, no ? So why he's waiting an array ?
Please help me, I'm going crazy...