symfony - 如何将 Symfony EasyAdmin 与具有构造函数的实体一起使用?
问题描述
EasyAdmin 是否支持具有不可为空属性的构造函数参数的实体类?即使您单击“添加”按钮,EasyAdmin 也会实例化实体类,对吗?不幸的是,这会导致“函数__construct() 的参数太少”错误。你有解决这个问题的方法吗?
我倾向于将构造函数用于不可为空的实体属性。不幸的是,当我单击 egAdd FiscalYear
按钮创建一个新的实体对象(FiscalYear
在我的示例中)时,EasyAdmin 会引发类似这样的错误:
Too few arguments to function App\Entity\FiscalYear::__construct(), 0 passed in /myProject/vendor/easycorp/easyadmin-bundle/src/Controller/AdminControllerTrait.php on line 618 and exactly 2 expected
如何防止这些错误?正如您在以下实体类中看到的那样,两个构造函数参数表示要通过表单提交的数据:
<?php
declare(strict_types=1);
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="App\Repository\FiscalYearRepository")
*/
class FiscalYear
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private ?int $id = null;
/**
* @ORM\Column(type="integer")
*/
private int $title;
/**
* @ORM\Column(type="boolean", options={"default": 0})
*/
private bool $completed = false;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Company", inversedBy="fiscalYears")
* @ORM\JoinColumn(nullable=false)
*/
private Company $company;
public function __construct(int $title, Company $company)
{
$this->title = $title;
$this->company = $company;
}
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): int
{
return $this->title;
}
public function setTitle(int $title): void
{
$this->title = $title;
}
public function getCompleted(): bool
{
return $this->completed;
}
public function setCompleted(bool $completed): void
{
$this->completed = $completed;
}
public function getCompany(): Company
{
return $this->company;
}
public function setCompany(Company $company): void
{
$this->company = $company;
}
}
是否有可能让 EasyAdmin 在不实例化实体类的情况下显示“创建新实体对象”表单?
解决方案
不,EasyAdmin 本身不支持带参数的构造函数。
为了避免这个问题,你有三个解决方案。
解决方案1:覆盖 EasyAdminController
// src/Controller/AdminController.php
namespace App\Controller;
use EasyCorp\Bundle\EasyAdminBundle\Controller\EasyAdminController;
class FiscalYearController extends EasyAdminController
{
public function createNewFiscalYearEntity()
{
//your own logic here to retrieve title and company
return new FiscalYear($title, $company);
}
}
根据您的业务模式,检索头衔和公司可能非常困难
解决方案2:尊重实体模式,用工厂模式帮助你的商业模式
- 您的实体应该尊重实体模式,并且应该编辑它们的构造函数以删除参数。
- 要在您的业务模型中替换您的构造函数,请创建一个工厂。
class FiscalYearFactory
{
public static function create(int $title, Company $company): FiscalYear
{
$fiscalYear = new FiscalYear();
$fiscalYear->setCompany($company);
$fiscalYear->setTitle($title);
return $fiscalYear;
}
}
在您的模型中,您必须进行一些更新:
//Comment code like this in your business model
$fiscalYear = new FiscalYear(2020,$company);
//Replace it, by this code:
$fiscalYear = FiscalYearFactory::create(2020,$company);
解决方案 3 在构造函数中接受空值。
我不喜欢这个解决方案。您的属性也应被编辑以接受空值,您的吸气剂应被编辑以返回空值。这是一个解决方案,但我不鼓励您使用它。
<?php
declare(strict_types=1);
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="App\Repository\FiscalYearRepository")
*/
class FiscalYear
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private ?int $id = null;
/**
* @ORM\Column(type="integer")
*/
private ?int $title;
/**
* @ORM\Column(type="boolean", options={"default": 0})
*/
private bool $completed = false;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Company", inversedBy="fiscalYears")
* @ORM\JoinColumn(nullable=false)
*/
private Company $company;
public function __construct(?int $title = null, ?Company $company = null)
{
$this->title = $title;
$this->company = $company;
}
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): ?int
{
return $this->title;
}
您应该使用第一个解决方案,这是一种更好的做法
推荐阅读
- vue.js - Vue 事件处理程序有时会传递 $event 对象,有时不会
- qt - 为 QML PathView 动画定义缓动
- mongodb - Spring-boot数据mongoDB查询嵌套列表
- php - 如何在 PHP 中获取枚举的所有值?
- python - 如何在所有文件中搜索字符串
- json - 是否可以从 statusjson.cgi 中得知 Nagios 监控的服务在 Nagios 上处于静默状态?
- python - ZipImportError 而工具链为 kivy-ios 编程构建 python3
- javascript - 如何在反应钩子中将单词进一步拆分为字母
- c# - Unity InputSystem 值持续输出 0,除非它从执行事件中读取
- matlab - 实施卡尔曼滤波器时设计矩阵 H 不正确