Kpihus
Kpihus

Reputation: 199

Symfony many-to-many

Usually i have solved many-to-many cases in the way of one-to-many-to-one way: first --< second >-- third. Code is implemented like described int this tutorial: http://www.prowebdev.us/2012/07/symfnoy2-many-to-many-relation-with.html and everything works like a charm.

ORM Designer offers and easy way to generate many-to-many relationships, and i decided to give it a try.

My entities are created by ORM Designer in following way:

Products Entity:

class Product {
<....>

/** 
 * @ORM\ManyToMany(targetEntity="Crm\AdminBundle\Entity\Memberships", inversedBy="Membershipses")
 * @ORM\JoinTable(
 *     name="MembershipsHasProduct", 
 *     joinColumns={@ORM\JoinColumn(name="Product_id", referencedColumnName="id", nullable=false)}, 
 *     inverseJoinColumns={@ORM\JoinColumn(name="Memberships_id", referencedColumnName="id", nullable=false)}
 * )
 */
private $Products;

<....>
}

In database it looks like:

CREATE TABLE IF NOT EXISTS `product` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `category_id` int(11) NOT NULL,
  `name` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
  `eanCode` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
  `productCode` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
  `description` longtext COLLATE utf8_unicode_ci,
  `deleted` tinyint(1) NOT NULL DEFAULT '0',
  `notes` longtext COLLATE utf8_unicode_ci,
  `createdTime` datetime NOT NULL,
  `virtual` tinyint(1) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `IDX_D34A04AD12469DE2` (`category_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=3 ;

Memberships entity:

class Memberships{
/** 
 * @ORM\ManyToMany(targetEntity="Crm\StockBundle\Entity\Product", mappedBy="Products", cascade={"all"})
 */
private $Membershipses;

}

In database it looks like:

CREATE TABLE IF NOT EXISTS `memberships` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `comembers` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=7 ;

MembershipsHasProduct table does not have entity symfony, still this table is generated in database:

CREATE TABLE IF NOT EXISTS `membershipshasproduct` (
  `Product_id` int(11) NOT NULL,
  `Memberships_id` int(11) NOT NULL,
  PRIMARY KEY (`Product_id`,`Memberships_id`),
  KEY `IDX_7FF740F6AD9658A` (`Product_id`),
  KEY `IDX_7FF740F6CFDFC8A4` (`Memberships_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

I've used Symfony's console app to auto generate form, and this is the result:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('name')
        ->add('comembers')
        ->add('Membershipses')
        ->add('Save','submit')
    ;
}

Form itself is working creat, products are presented in picklist (by field 'Membershipses') and Membership data is saved into database. But 'MembershipsHasProduct' table does not get any data in database.

I assume i have something 'Special' to do, in order to get this table filled with Membership-Product relation data ?

Upvotes: 1

Views: 1224

Answers (1)

shacharsol
shacharsol

Reputation: 2342

You need to implement add methods like the following:

/**
 * {@inheritDoc}
 */
public function addMembership($membership)
{
    if (!$this->getMemberhips()->contains($membership)) {

        $this->getMemberhips()->add($membership);
        $membership->addProduct($this);

    }

    return $this;
}

And initiate the membership collection on constructor:

public function _construct(){
 $this->memberships = new ArrayCollection();

}

Upvotes: 4

Related Questions