【问题标题】:Q: Symfony4 EasyAdmin oneToMany not saving in DB问:Symfony4 EasyAdmin oneToMany 没有保存在数据库中
【发布时间】:2018-06-26 12:40:43
【问题描述】:

我有 2 个实体,产品(产品)和制造商(制造商)。

当我尝试从 Easy Admin 更新它们时,如果我在产品端更改制造商,一切都很好,它可以正常工作,并且制造商管理员确实显示了适量的子产品。

但是,如果我反过来 - 从制造商管理员中选择子产品 - 它不会将其保存在数据库中。它确实保存名称,但不保存子列表。

这里和那里的一些主题表明我必须确保在 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 } }

【问题讨论】:

  • 我有完全相同的问题:(
  • 我没有做过的一个测试是在 Symfony 3 环境中复制相同的情况,这至少有助于确定问题是与 SF4 相关还是与 EasyAdmin 相关,我会尽快尝试

标签: symfony one-to-many symfony2-easyadmin


【解决方案1】:

原因是 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();
    }
}

【讨论】:

    【解决方案2】:

    issue appears very often 我自己也遇到了。这是我的解决方案,没有覆盖任何控制器操作:

    对于使用 EasyAdminBundle v1.17.08 - v1.17.22 的任何人,您应该先升级。显然Issue #1679 引入了导致此错误的错误。

    下一步是确保已设置拥有实体中的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);
    } 
    

    【讨论】:

    • 级联部分对我帮助很大。以防万一,无需移除孤儿。
    【解决方案3】:

    这对我有用

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

    【讨论】:

      猜你喜欢
      • 2018-11-05
      • 2020-08-26
      • 2021-03-09
      • 2013-11-26
      • 1970-01-01
      • 2012-12-16
      • 2020-06-18
      • 2020-12-01
      • 1970-01-01
      相关资源
      最近更新 更多