nbro
nbro

Reputation: 15837

Check if a entity already exists in the database using Symfony and Doctrine

So, here's my situation. I've 3 tables, tag, product and tag_product, which is created from annotations of a "many-to-many" relationship between tag and product, i.e. a tag can be associated with many products and a product can have many tags associated with it.

Now, I'm using a data transformer to transform the Tag objects to a string composed of the tags separate by commas whenever the user wants to edit a product.

In the Tag entity I've a primary key, an id, and a unique field, the name of the tag. I don't essentially want to have two tags with the same name.

My problem is that I don't know how to access the "new" tags chosen by the user when the form has been submitted to update the product. Is there a way to do it? Accessing the request may only be useful to access the input string of tags, but not the Tag objects created from that string in the data transformer.

I could also pass the current $product object to buildForm, which would pass it to the data transformer mentioned above, but this doesn't seem a good solution, when an object is passed around (at least to me). Also I would need to create another entity manager from the data transformer and do things that a data transformer shouldn't do.

Any better ideas?

Edit

I've just thought that maybe I could just check when inserting the tag in the ArrayCollection of the product if that same ArrayCollection already contains a tag with the same name of the being inserted tag, but since I don't know if that collection will be already filled with the current tags or not, at that moment...

Edit 2

The solution in the previous edit doesn't work for me, I guess, again, because that array collection is empty when the new tag is inserted...

Upvotes: 1

Views: 3707

Answers (1)

kero
kero

Reputation: 10638

Not sure if this is best practice, but what I have done in the past is use the following ModelTransformer

// ArrayCollection of tags to string
function ($tags)
{
    if ($tags === null)
        return '';

    return implode(',', array_map(function($tag){
        return $tag->getName();
    }, $tags->toArray()));
}

// string to ArrayCollection of tags
function ($string)
{
    $tags = new \Doctrine\Common\Collections\ArrayCollection();

    if ($string === '' || $string === null)
        return $tags;

    $array = explode(',', $string);
    foreach ($array as $tagName) {
        $tag = $this->em
            ->getRepository('AppBundle:Tag')
            ->findOrCreateByName($tagName);
        $tags->add($tag);
    }

    return $tags;
}

Where the key actually is the findOrCreateByName() method in the TagRepository

public function findOrCreateByName($name)
{
    $name = trim($name);

    $tag = self::findOneBy(['name' => $name]);

    if ($tag === null) {
        $tag = new Tag;
        $tag->setName($name);
    }

    return $tag;
}

Upvotes: 1

Related Questions