如何将Symfony EasyAdmin与具有构造函数的实体一起使用?
EasyAdmin是否支持为不可为null的属性提供构造函数参数的实体类?即使单击“添加”按钮,EasyAdmin也会实例化实体类,对吗?不幸的是,这会导致“参数太少,无法使用函数_construct()”错误。你有解决这个问题的办法吗 我倾向于对不可为null的实体属性使用构造函数。不幸的是,当我点击例如如何将Symfony EasyAdmin与具有构造函数的实体一起使用?,symfony,easyadmin,Symfony,Easyadmin,EasyAdmin是否支持为不可为null的属性提供构造函数参数的实体类?即使单击“添加”按钮,EasyAdmin也会实例化实体类,对吗?不幸的是,这会导致“参数太少,无法使用函数_construct()”错误。你有解决这个问题的办法吗 我倾向于对不可为null的实体属性使用构造函数。不幸的是,当我点击例如Add FiscalYear按钮创建一个新的实体对象时(在我的示例中,FiscalYear),EasyAdmin会抛出类似这样的错误: 如何防止这些错误?正如您在以下实体类中所看到的,两个构造
Add FiscalYear
按钮创建一个新的实体对象时(在我的示例中,FiscalYear
),EasyAdmin会抛出类似这样的错误:
如何防止这些错误?正如您在以下实体类中所看到的,两个构造函数参数表示要通过表单提交的数据:
<?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本机不支持带参数的构造函数
为了避免这个问题,您有三种解决方案
解决方案1:覆盖EasyAdminController
//src/Controller/AdminController.php
名称空间App\Controller;
使用EasyCorp\Bundle\EasyAdminBundle\Controller\EasyAdminController;
类FiscalYearController扩展EasyAdminController
{
公共函数createNewFiscalYearEntity()
{
//您自己的逻辑在这里检索标题和公司
返回新财政年度($title,$company);
}
}
根据您的业务模式,检索标题和公司可能非常困难
解决方案2:尊重实体模式,用工厂模式帮助您的业务模式
您的实体应该尊重实体模式,并且应该编辑它们的构造函数以删除参数李>
要替换业务模型中的构造函数,请创建工厂
类财务工厂
{
公共静态函数create(int$title,Company$Company):FiscalYear
{
$fiscalYear=新的fiscalYear();
$FISCALIEAR->setCompany($company);
$FISCALIEAR->setTitle($title);
返回$FISCALIEAR;
}
}
在您的模型中,您必须进行一些更新:
//在您的业务模型中对这样的代码进行注释
$FISCALIEAR=新的FISCALIEAR(2020,$company);
//将其替换为以下代码:
$FISCALIEAR=FISCALIEARFactory::创建(2020,$company);
解决方案3接受构造函数中的空值。
我不喜欢这个解决方案。您的属性也将被编辑以接受空值,您的getter将被编辑以返回空值。这是一个解决方案,但我不鼓励你使用它
这似乎不是一个有用的选项:Thx。不幸的是,解决方案1不是一个选项,因为两个构造函数参数$title
和$company
是要由编辑器在表单中设置的数据(部分)。解决方案2可能有效,但我不确定是否要用静态create()
方法替换构造函数。我同意应该避免解决方案3。我理解你所说的解决方案2。经过多年的开发(和bug:),我现在确信在构造函数中添加参数不是一个好的实践。当我在构造器中添加参数时,您将我的业务模型与实体混合在一起,我现在避免使用它,因为实体只在这里存储。里面没有逻辑,只有getter和setter。或者你也可以在EasyAdmin中遇到类似的bug。
<?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;
}
}