问:Symfony4 EasyAdmin一对多未保存在数据库中

txu3uszq  于 2023-02-13  发布在  其他
关注(0)|答案(4)|浏览(125)

我有2个实体,产品(Produit)和制造商(Fabricant)。
当我试图从轻松管理更新它们时,如果我在产品方面更改制造商,一切都很好,它工作正常,制造商管理确实显示了适量的子产品。
然而,如果我用相反的方法--从制造商管理中选择子产品--它不会将其保存在数据库中,而是保存名称,但不保存子列表。
这里和那里的一些主题表明,我必须确保在addProduct函数中,我也使用$product-〉setManufacturer($this)对产品进行操作;......我已经这么做了(见下面的代码)。
其他人提到,在管理配置中,我应该把by_reference选项设置为false。我也这样做了。但没有成功。
另一个建议是确保级联是正确的2个实体之间,我已经把它"全部",直到我能找出什么是错的,但它仍然不工作。没有错误消息,没有警告,它甚至保存其他字段,但不是这个。任何想法?
产品名称:

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

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

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

    /**
     * @ORM\ManyToOne(targetEntity="Fabricant", inversedBy="produits", cascade="all")
     */
    private $fabricant;

    public function __toString()
    {
        return ($this->nom != null) ? $this->nom : '';
    }

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

    public function setId($id)
    {
        $this->id = $id;

        return $this;
    }

    public function getNom()
    {
        return $this->nom;
    }

    public function setNom($nom)
    {
        $this->nom = $nom;

        return $this;
    }

    public function getFabricant()
    {
        return $this->fabricant;
    }

    public function setFabricant($fabricant)
    {
        $this->fabricant = $fabricant;

        return $this;
    }
}

制造商:

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

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

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

    /**
     * @ORM\OneToMany(targetEntity="Produit", mappedBy="fabricant", cascade="all")
     */
    private $produits;

    public function __toString()
    {
        return ($this->nom != null) ? $this->nom : '';
    }

    public function __construct()
    {
        $this->produits = new ArrayCollection();
    }

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

    public function setId($id)
    {
        $this->id = $id;

        return $this;
    }

    public function getNom()
    {
        return $this->nom;
    }

    public function setNom($nom)
    {
        $this->nom = $nom;

        return $this;
    }

    public function getProduits()
    {
        return $this->produits;
    }

    public function addProduit(Produit $produit)
    {
        if ($this->produits->contains($produit)) {
            return;
        }
        $this->produits[] = $produit;
        $produit->setFabricant($this);
        return $this;
    }

    public function removeProduit($produit)
    {
        $this->produits->removeElement($produit);
        $produit->setFabricant(null);
    }
}

轻松管理yaml配置:

easy_admin:
    entities:
        Produit:
            class: App\Entity\Produit
            list:
                fields:
                    - id
                    - nom
                    - fabricant
            new:
                fields:
                    - nom
                    - { property: 'fabricant', type_options: { 'by_reference': false } }
        Fabricant:
            class: App\Entity\Fabricant
            list:
                fields:
                    - id
                    - nom
                    - produits
            new:
                fields:
                    - nom
                    - { property: 'produits', type_options: { by_reference: false } }
            edit:
                fields:
                    - nom
                    - { property: 'produits', type_options: { multiple: true, by_reference: false } }
dzhpxtsq

dzhpxtsq1#

原因是bug in EasyAdmin controller调用了带有具体$entity的flush(),因此其他更改不会持久化。您可以等待新版本或extend AdminController and override methods
控制类别变更:

easy_admin_bundle:
    resource: 'App\Controller\AdminController'
    prefix: /admin
    type: annotation

扩展管理控制器:

<?php
namespace App\Controller;

use EasyCorp\Bundle\EasyAdminBundle\Controller\AdminController as BaseAdminController;

class AdminController extends BaseAdminController
{
    protected function persistEntity($entity)
    {
        $this->em->persist($entity);
        $this->em->flush();
    }

    protected function updateEntity($entity)
    {
        $this->em->flush();
    }

    protected function removeEntity($entity)
    {
        $this->em->remove($entity);
        $this->em->flush();
    }
}
des4xlb0

des4xlb02#

这个问题经常出现,我自己也遇到过。下面是我的解决方案,没有覆盖任何控制器操作:
对于任何使用EasyAdminBundle v1.17.08 - v1.17.22的人,你应该先升级。显然Issue #1679引入了一个bug,导致了这个错误。
下一步是确保所有实体中的cascade选项已设置:

@ORM\OneToMany(targetEntity="PageBlock", mappedBy="page", cascade="all", orphanRemoval=true)

还要在表单中设置by_reference选项:

# in your easy_admin config block...
      - property: 'blocks'
        type: 'collection'
        type_options:
          entry_type: ...PageBlockType
          by_reference: false

最后但并非最不重要的是,我在父实体中缺少addremove方法。还要确保命名是正确的。因此,对于名为$blockproperty,请使用以下命令:

public function addBlock(PageBlock $block) : void
{
    $block->setPage($this);
    $this->blocks->add($block);
}

public function removeBlock(PageBlock $block) : void
{
    $block->setPage(null);
    $this->blocks->remove($block);
}
db2dz4w8

db2dz4w83#

这对我很有效

form:
    fields:
      - { property: 'school' }
      - { property: 'companies', type_options: { by_reference: false } }
wecizke3

wecizke34#

对于easyadmin4,这对我很有效:

$events = AssociationField::new('events')->setFormTypeOption('by_reference', false);

相关问题