Ahoj, mám entitu produkt a ten by měl mít možnost vlastnit více attributů. Mám to navržené tedy přes spojovací tabulku. Pro přidávání attributů používám replicator. Jak pěkně uložit nové attributy?

Udělal jsem tam něco takového:

foreach ($values["attributes"] as $key => $attribute)
{
    $a = new CatalogItemAttribute();
    $a->value = $attribute->value;
    $a->attribute = $this->attributeModel->findAttribute($attribute->id);
    $this->entity->addAttribute($a);

    $this->em->persist($this->entity);
}

$this->em->flush($entity);

ale křičí:

A new entity was found through the relationship 'App\Entity\CatalogItem#attributes' that was not configured to cascade persist operations for entity: App\Entity\CatalogItemAttribute@00000000154b019f000000000e5b71bb. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"}). If you cannot find out which entity causes the problem implement 'App\Entity\CatalogItemAttribute#__toString()' to get a clue.

Jednotlivé entity:

CatalogItem:

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="catalog_item")
 */
class CatalogItem extends BaseEntity
{
    use \Kdyby\Doctrine\Entities\MagicAccessors;

    /**
     * @ORM\Id
     * @ORM\Column
     * @ORM\GeneratedValue
     */
    protected $id;

    /**
     * @ORM\Column
     * @InputType(label="Název", type="text", required=true)
     */
    protected $name;

    /**
     * @ORM\Column
     * @InputType(label="Model", type="text", required=true)
     */
    protected $model;

    /**
     * @ORM\Column
     * @InputType(label="URL", type="text", required=true)
     */
    protected $url;

    /**
     * @ORM\Column
     * @InputType(label="Vlastní H1", type="text")
     */
    protected $titleH1;

    /**
     * @ORM\Column
     * @InputType(label="Meta title", type="text")
     */
    protected $metaTitle;

    /**
     * @ORM\Column
     * @InputType(label="Meta description", type="textArea")
     */
    protected $metaDescription;

    /**
     * @ORM\Column(type="decimal")
     * @InputType(label="Cena bez DPH", type="text")
     */
    protected $price;

    /**
     * @ORM\Column(type="decimal")
     * @InputType(label="Cena s DPH", type="text")
     */
    protected $priceWithoutVat;

    /**
     * @ORM\Column
     * @InputType(label="DPH v %", type="text")
     */
    protected $vat;

    /**
     * @ORM\OneToMany(targetEntity="CatalogCategoryItem", mappedBy="item")
     */
    protected $categories;

    /**
     * @ORM\ManyToOne(targetEntity="CatalogCategory")
     */
    protected $category;

    /**
     * @ORM\Column
     * @InputType(label="Popis", type="textArea")
     * @InputStyle(class="editor")
     */
    protected $description;

    /**
     * @ORM\Column
     */
    protected $image;

    /**
     * @ORM\Column
     */
    protected $photo = null;

    /**
     * @ORM\Column
     */
    protected $variant;

    /**
     * @ORM\OneToMany(targetEntity="CatalogItemVariant", mappedBy="item")
     */
    protected $variants = null;


    /**
     * @ORM\OneToOne(targetEntity="CatalogItemVariant", mappedBy="variant")
     */
    protected $variantsOf = null;


    /**
     * @ORM\Column
     * @InputType(label="Počet kusů", type="text")
     */
    protected $quantity;


    /**
     * @param $item
     * @return mixed
     */
    private static function getVariant($item) {
        return $item->variant;
    }

    /**
     * Get price of Vat
     * @return mixed
     */
    public function getVatPrice()
    {
        return $this->price - $this->priceWithoutVat;
    }

    /**
     * @ORM\OneToMany(targetEntity="CatalogItemAttribute", mappedBy="item")
     */
    protected $attributes = null;


    public function addAttribute(CatalogItemAttribute $attribute)
    {
        $attribute->item = $this;
        $this->attributes[] = $attribute;
    }

    /**
     * Get array of product variants
     * @return array
     */
    public function getVariants() {

        if($this->variant == 0)
        {
            $result = array();

            foreach($this->variants as $variant) {
                $result[] = $variant->variant;
            }

            return $result;
        }

        $variants = isset($this->variantsOf) ? $this->variantsOf->item->getVariants() : array();
        $result = array();

        foreach($variants as $var) {
            if($var->id != $this->id)
               $result[] = $var;
        }

        if(isset($this->variantsOf))
        $result[] = $this->variantsOf->item;
        return $result;
    }

    /**
     * Return array of product attributes, todo !!!!
     * @return array
     */
    public function getAttributes()
    {
        $results = [];

        return $results;
    }

    /**
     * Return array of product attachments, todo !!!!
     * @return array
     */
    public function getAttachments()
    {
        $results = [];

        return $results;
    }

}

CatalogAttribute:

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="catalog_attribute")
 */
class CatalogAttribute extends BaseEntity
{
    use \Kdyby\Doctrine\Entities\MagicAccessors;

    /**
     * @ORM\Id
     * @ORM\Column
     * @ORM\GeneratedValue
     */
    protected $id;

    /**
     * @ORM\Column
     */
    protected $type;

    /**
     * @ORM\Column
     */
    protected $title;

    /**
     * @ORM\Column
     */
    protected $value;

    /**
     * @ORM\Column
     */
    protected $unit;

    /**
     * @ORM\OneToMany(targetEntity="CatalogItemAttribute", mappedBy="attribute")
     */
    protected $items;
}

CatalogItemAttribute:

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="catalog_item_attributes")
 */
class CatalogItemAttribute
{
    use \Kdyby\Doctrine\Entities\MagicAccessors;

    /**
     * @ORM\Id
     * @ORM\Column
     * @ORM\GeneratedValue
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="CatalogItem", cascade={"persist"})
     * @ORM\JoinColumn(name="id_item", referencedColumnName="id")
     */
    protected $item;

    /**
     * @ORM\OneToOne(targetEntity="CatalogAttribute", inversedBy="items")
     * @ORM\JoinColumn(name="id_attribute", referencedColumnName="id")
     */
    protected $attribute;

    /**
     * @ORM\Column
     */
    protected $value;
}

Nakopnete mě správným směrem prosím?

Chyba byla v ukládání, tj persist:

foreach ($values["attributes"] as $key => $attribute)
{
    $a = new CatalogItemAttribute();
    $a->value = $attribute->value;
    $a->attribute = $this->attributeModel->findAttribute($attribute->id);
    $this->entity->addAttribute($a);

    $this->em->persist($a);
}

$this->em->flush($entity);
  • Jak s tím pracovat v případě replicatoru?
  • Jak zajistit automatické mazání, když přes replicator odstraním řádek?
  • Jak zajistit updatování, aniž by se tvořili duplicity?

Provizorně všechny záznamy před zpracováním smažu, ale asi to není cool řešení:

$this->em->getConnection()->delete('catalog_item_attributes', ['catalog_item_id' => $this->entity->id])

Nikdo? :-(


You must first log in to participate in this discussion