在哪里向实体添加自定义字段?

Where to add custom fields to entity?

我正在使用 SonataAdmin 并且有十几个实体和一个控制器。大多数 CMS 只是将数据库中的实体字段 as-is 显示到我的视图中。我想向我的实体添加一些自定义字段,数据将跨越多个字段(这意味着在我的 Car 实体上,我还想查询 Driver 和 License 实体。)

这是我的汽车和 Driver 个实体的示例:

<?php

namespace Scholar\AdminBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Car
 *
 * @ORM\Table(name="Car", indexes={@ORM\Index(name="id", columns={"id"})})
 * @ORM\Entity
 */
class Car
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var int
     *
     * @ORM\Column(name="driverId", type="integer", nullable=false)
     */
    private $driverId;

  // ...

}

use Doctrine\ORM\Mapping as ORM;

/**
 * Driver
 *
 * @ORM\Table(name="Driver", indexes={@ORM\Index(name="id", columns={"id"})})
 * @ORM\Entity
 */
class Driver
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="firstName", type="string", nullable=false)
     */
    private $firstName;

  // ...

}

以及我如何添加要为每个实体显示的字段(通过扩展 Admin):

<?php

namespace Scholar\AdminBundle\Admin;

use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Route\RouteCollection;
use Sonata\AdminBundle\Show\ShowMapper;

class CarAdmin extends Admin
{
    protected function configureRoutes(RouteCollection $collection)
    {
        $collection->add('sync');
        $collection->remove('create');
        $collection->remove('delete');
    }

    /**
     * @param DatagridMapper $datagridMapper
     */
    protected function configureDatagridFilters(DatagridMapper $datagridMapper)
    {
        $datagridMapper
            ->add('firstName');
    }

    /**
     * @param ListMapper $listMapper
     */
    protected function configureListFields(ListMapper $listMapper)
    {
        $listMapper
            ->addIdentifier('id')
            ->addIdentifier('firstName')
        // ...
    }

我想向 Car 实体添加一个 numberOfDrivers 字段。我有查询工作(使用 queryBuilder。)我显然必须查询 Car 和 Driver 实体(以及其他一些。)我的问题是,要将此自定义字段添加到 Car 实体,在哪里放置跨多个实体进行查询的方法的最佳位置,然后如何将其添加到我的数据过滤器并让它可以在我的 $listMapper

中访问

这样我就可以像这样在汽车管理页面上显示 numberOfDrivers 并允许对其进行排序:

    /**
     * @param DatagridMapper $datagridMapper
     */
    protected function configureDatagridFilters(DatagridMapper $datagridMapper)
    {
        $datagridMapper
            ->add('firstName');
            ->add('numberOfDrivers');
    }

    /**
     * @param ListMapper $listMapper
     */
    protected function configureListFields(ListMapper $listMapper)
    {
        $listMapper
            ->addIdentifier('id')
            ->addIdentifier('firstName')
            ->addIdentifier('numberOfDrivers')
        // ...
    }

谢谢!

我的第一个方法是让 ORM 完成工作。如果我理解正确的话,一辆汽车可以有多个 driver,而一个 driver 可以驱动多辆汽车。所以你有一个标准的 many-to-many 关系。

因此在您定义的 Car orm 元数据中(例如 Car.orm.xml):

<many-to-many field="drivers" target-entity="Driver">
  <join-table name="car2driver">
    <join-columns>
      <join-column name="driver_id" referenced-column-name="id" />
    </join-columns>
    <inverse-join-columns>
      <join-column name="car_id" referenced-column-name="id" />
    </inverse-join-columns>
  </join-table>
</many-to-many>

在您初始化的 Car 实体的构造函数中:

private $drivers;

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

添加新字段

private $numberOfDrivers;

与相应的getter。 getter 应如下所示:

public function getNumberOfDrivers()
{
   $this->drivers->count();
}

您现在应该可以使用 'numberOfDrivers' 如上所述。