Как использовать Symfony EasyAdmin с объектами, имеющими конструктор? - PullRequest
1 голос
/ 16 апреля 2020

Поддерживает ли EasyAdmin классы сущностей с аргументами конструктора для свойств, которые должны быть не обнуляемыми? EasyAdmin создает экземпляр класса сущности, даже если вы нажмете кнопку «Добавить», верно? К сожалению, это приводит к ошибке «Слишком мало аргументов для функции __construct ()». У вас есть решение этой проблемы?

Я склонен использовать конструктор для свойств сущностей, которые не могут быть обнулены. К сожалению, EasyAdmin выдает подобные ошибки, когда я нажимаю, например, кнопку Add FiscalYear, чтобы создать новый объект сущности (FiscalYear в моем примере):

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 показать «создать новый объект сущности» "форма без создания экземпляра класса сущности?

1 Ответ

1 голос
/ 16 апреля 2020

Нет, 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: Уважайте шаблон сущностей и помогите вашей бизнес-модели с фабричным шаблоном

  1. Ваши сущности должны уважать шаблон сущностей, и их конструктор должен быть отредактирован для удаления аргументов.
  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);

Solution3 Примите пустые значения в вашем конструкторе.

Мне не нравится это решение. Ваши свойства должны быть отредактированы так, чтобы принимать нулевые значения, ваши получатели должны быть отредактированы так, чтобы они возвращали нулевое значение. Это решение, но я не рекомендую вам его использовать.

<?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;
    }

Вы должны использовать первое решение, которое является лучшей практикой

...