Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper way to check if many-to-many relation exists - Symfony2/Doctrine

Let's suppose I have two entities User and Product related by a Many-to-Many relationship with Doctrine.

I would like to know the best way to handle a $user->hasProduct($product) method for my User entity that returns true is relation exists or false if not.

I'm currently doing this :

public function hasProduct($id)
{
    foreach($this->getProducts() as $product) {
        if($product->getId() == $id) {
            return true;
        }
    }

    return false;
}

But i'm not sure it's the best way, especially if there is many relations in the loop.

If someone has something better, let me know :)

like image 338
Thomas Piard Avatar asked Jan 24 '13 14:01

Thomas Piard


2 Answers

Your function getProducts gives you an ArrayCollection.

Just do

if($user->getProducts()->contains($product)) //the real product object not the id
       //your stuff

Edit :

For twig template :

{% if product in user.products %}
    //your stuff
{% endif %}
like image 85
Pierrickouw Avatar answered Nov 15 '22 00:11

Pierrickouw


I was struggling with the same problem, and came across this blog entry which solved this problem by making use of Doctrine Filters.

If I understand your problem correctly and you have three tables (user, user_product and product) you should be able to rewrite your hasProduct($id) function like this:

use Doctrine\Common\Collections\Criteria;

public function hasProduct(int $productId): bool {

  $criteria = Criteria::create();
  $criteria->where(Criteria::expr()->eq('id', $productId));

  if(count($this->products->matching($criteria)) > 0) {
    return true;
  }

  return false;
}

When running this code, Doctrine does not load all the Products linked to the User. It in fact only queries the cross reference table (user_product).

like image 21
pluk77 Avatar answered Nov 14 '22 22:11

pluk77