Many-to-Many Association Doctrine Update

Is there a solution to do this automatically?

My two objects:

class User
{
    /* *
    * @ManyToMany(targetEntity="Product", inversedBy="users")
    * @JoinTable(name="user_product",
    *  joinColumns={@JoinColumn(name="user_id", referencedColumnName="idUser")},
    * inverseJoinColumns={@JoinColumn(name="product_id", referencedColumnName="idProduct")}
    * 
    * )
    */
protected $products;
}

class Product {
    /**
    * @ManyToMany(targetEntity="User", mappedBy="products")
    */
protected $users;
}

A user exists with two Products ( 1, 2) identifiers already associated :

$user = $entityManager->find('User', 1);

This array came from a view with new products, data that needs to be inserted, deleted, or if nothing is already in the list:

$array = array(1, 3, 4);

In this case:

1 = Already in association with User (do nothing)
2 = not in array and should be deleted
3 = should be inserted
4 = should be inserted

How to do it in doctrine 2? Is there a merge function that does this automatically or shoud I do it manually?

+4
source share
1 answer

Consider the following code

$user = $entityManager->find('User', 1);
$products = array();

foreach(array(1, 3, 4) as $product_id) {
    $products[$product_id] = $entityManager->getReference('MyBundle\Entity\Product', $product_id);
}

$user->setProducts($products);    
$entityManager->persist($user);
$entityManager->flush();

And is setProductsdefined as

function setProducts($products) {
  $this->products = new ArrayCollection($products);
}

, , .

, visit visit_tag. , visit_tag visit , .

enter image description here

/ , $user->products ArrayCollection , , . , indexBy, // (.. product id) .

class User
{
   /**
    * @ManyToMany(targetEntity="Product", inversedBy="users", indexBy="id")
    * @JoinTable(name="user_product",
    *  joinColumns={@JoinColumn(name="user_id", referencedColumnName="idUser")},
    * inverseJoinColumns={@JoinColumn(name="product_id", referencedColumnName="idProduct")}
    * )
    */
    protected $products;

    public function setProducts($products) {
        foreach($this->products as $id => $product) {
            if(!isset($products[$id])) {
                //remove from old because it doesn't exist in new
                $this->products->remove($id);
            }
            else {
                //the product already exists do not overwrite
                unset($products[$id]);
            }
        }

        //add products that exist in new but not in old
        foreach($products as $id => $product) {
            $this->products[$id] = $product;
        }    
    }
}

, ( ) .

enter image description here

, , db , . :

1

  • ,

2

  • ,
  • ,

2 , . , , 1, , .

+7

Source: https://habr.com/ru/post/1545589/


All Articles