1

I have a entity Annonce has Tags ManyToMany to Entity Tag

When i search an Annonce by tags like this picture

enter image description here

My probleme is : For example If the Bike tags exist in Database that will return Annonces with that tag, without errors

If i add for example Tags Like "Car" is ,no exist in database, an error is appear :

Binding entities to query parameters only allowed for entities that have an identifier.

This is in my controller

$annonces = $repository->findListByFilter($data->getTags());

and this is the repository

public function findListByFilter($tags):array
{
    return $this->createQueryBuilder('c')
        ->innerJoin('c.tags', 'tags')
        ->where('tags IN (:value)')
        ->setParameter(':value', $tags)
        ->getQuery()->getResult();
}

there's a solution to resolve this probleme?

----------Additional information--------------- Tag Entity

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\TagRepository")
 */
class Tag
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $titre;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getTitre(): ?string
    {
        return $this->titre;
    }

    public function setTitre(string $titre): self
    {
        $this->titre = $titre;

        return $this;
    }

    public function __toString()
    {
        return $this->titre;
    }
}

Annonce Entity

namespace App\Entity;

use App\Tag\Taggable;
class Annonce
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    public function __construct()
    {

        $this->tags = new ArrayCollection();

    }

    use Taggable;
}

Class Taggable

use App\Entity\Tag;

trait Taggable
{

    /**
     * @var array
     *php bin/console make:entity --regenerate App
     * @ORM\ManyToMany(targetEntity="App\Entity\Tag", cascade={"persist"})
     */
    private $tags;

    /**
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getTags()
    {
        return $this->tags;
    }

    public function addTag(tag $tag)
    {
        if (!$this->tags->contains($tag)) {
            $this->tags[] = $tag;
        }
        return $this;
    }

    public function removeTag(tag $tag)
    {
        if ($this->tags->contains($tag)) {
            $this->tags->removeElement($tag);
        }

    }

    public function __construct()
    {
        $this->tags = new ArrayCollection();
    }
}
Khalil
  • 288
  • 3
  • 16
  • Show the content from `$data->getTags()` with `var_dump()` – Fabian Schmick Mar 13 '19 at 08:47
  • object(Doctrine\Common\Collections\ArrayCollection)#931 (1) { ["elements":"Doctrine\Common\Collections\ArrayCollection":private]=> array(1) { [0]=> object(App\Entity\Tag)#1243 (2) { ["id":"App\Entity\Tag":private]=> int(1) ["titre":"App\Entity\Tag":private]=> string(7) "symfony" } } } – Khalil Mar 13 '19 at 08:49

1 Answers1

1

You can do either of these two options here:

  1. Store that new tag in DB also, then proceed with findListByFilter()

  2. Don't store the new tag, but modify:

In controller:

$annonces = $repository->findListByFilter($data->getTags());

In repository:

public function findListByFilter($tags):array
{
    $tagsText = [];
    foreach ($tags as $tag) {
      $tagsText[] = $tag->getTitre();
    }

    return $this->createQueryBuilder('c')
        ->innerJoin('c.tags', 'tags')
        ->where('tags.titre IN (:value)')
        ->setParameter(':value', $tagsText)
        ->getQuery()->getResult();
}

I'm assuming here that the tag entity has the field text.

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
programmer-man
  • 365
  • 3
  • 12