Lucio
Lucio

Reputation: 642

symfony2 - ManyToMany with duplicate rows

I currently have to Entities in my application:

A Page can have many Blocks, which are shared across many Pages, so it is quite obvious that the relation is a ManyToMany. However, I need to be able to add the same Block twice (or more) to the same Page. Doctrine creates the "page_block" join table automatically, but with page_id and block_id both as Primary Keys, therefore adding a duplicate throws an error.

Is it possible, without adding an additional Entity, to tell doctrine to allow duplicates on the Page--Block relation ?

Upvotes: 2

Views: 920

Answers (1)

abdiel
abdiel

Reputation: 2106

Well, I'm not sure about that behavior in doctrine, but if that is the case, then you can do something that I almost always do. Represent the ManyToMany relation as two OneToMany-ManyToOne. You must create your own PageBlock entity and configure it's foreign keys.

class Page{
    /**
     * @var array
     *
     * @ORM\OneToMany(targetEntity="PageBlock", mappedBy="page", cascade={"all"})
     */
    private $pageBlocks;
}

class Block{
        /**
         * @var array
         *
         * @ORM\OneToMany(targetEntity="PageBlock", mappedBy="block", cascade={"all"})
         */
        private $pageBlocks;
    }

class PageBlock{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var \stdClass
     *
     * @ORM\ManyToOne(targetEntity="Page", inversedBy="pageBlocks")
     * @ORM\JoinColumn(name="id_page", referencedColumnName="id")
     */
    private $page;

    /**
     * @var \stdClass
     *
     * @ORM\ManyToOne(targetEntity="Block", inversedBy="pageBlocks")
     * @ORM\JoinColumn(name="id_block", referencedColumnName="id")
     */
    private $block;
  }

As you can see the primary key remains as ID, so problem resolved. I say almost always do because this is how I do it if I need an extra attribute in the relation(almost always it happens). I suspect that could be a way of do it with the ManyToMany annotation, but there is no difference with this approach.

Hope this help you.

Upvotes: 1

Related Questions