在单个字段下映射多个实体



有没有一种方法可以将实体中的单个字段绑定到多个不同的实体?

我有一个"任务"实体,它可以与客户实体或供应商实体关联(决不能两者都关联(。现在这两个字段是分开的。

我需要在我的TaskType表单中使用它,这样用户就可以选择将任务与哪个客户/供应商关联,最好是在一个字段下,因为我计划添加更多可以与之关联的实体。

/**
* @ORMManyToOne(targetEntity="AppEntityCustomer", inversedBy="tasks")
*/
private $customer;
/**
* @ORMManyToOne(targetEntity="AppEntitySupplier", inversedBy="tasks")
*/
private $supplier;
public function getCustomer(): ?Customer
{
return $this->customer;
}
public function setCustomer(?Customer $customer): self
{
$this->customer = $customer;
return $this;
}
public function getSupplier(): ?Supplier
...etc

也许您可以尝试以下操作:

理想情况下,我想您希望在CustomerSupplier之间共享信息。因此,我们可以引入一个新的父类,例如Person(我不知道他们有哪种责任,所以我们将使用最"通用"的类名(,并使用条令继承映射:

<?php
namespace AppEntity;
use DoctrineORMMapping as ORM;
/**
* @ORMEntity
* @ORMInheritanceType("JOINED")
* @ORMDiscriminatorColumn(name="discr", type="string")
* @ORMDiscriminatorMap({
*  "customer" = "Customer",
*  "supplier" = "Supplier"
* })
*/
abstract class Person
{
//... Fields, traits, embeddables...
/**
* A common attribute between our child classes
* protected to respect encapsulation
* 
* @ORMColumn(type="text")
*/
protected $name;
/**
* Here we define the general link to a task. It will be inherited by child classes
*
* @ORMOneToMany(targetEntity="AppEntityTask", mappedBy="assignedTo")
*/
protected $tasks;
// public getters/setters...
}

我认为类表继承策略将满足您的需求,因为您稍后需要添加更多实体。这样,我们就可以尊重开放-封闭原则,以后添加更多的子类,而不是只修改一个类中的逻辑。

此外,由于我们通常想要处理CustomerSupplier实例,所以我将Person类设为抽象类。但根据您的需要,也许您可以删除abstract关键字。在这种情况下,必须在鉴别器映射中包含Person

当然,现在CustomerSupplier都必须扩展Person:

//...
class Customer extends Person
//...
//...
class Supplier extends Person
//...

不要忘记从子类中删除共享字段(例如id(,它现在将从Person继承

因此,在Task中,您可以定义ManyToOnePerson:的关系

/**
* @ORMManyToOne(targetEntity="AppEntityPerson", inversedBy="tasks")
*/
private $assignedTo;

最后,对于您的任务表单,让我们有一个包含所有人员姓名的选择列表:

<?php
namespace AppForm;
use AppEntityPerson;
use AppEntityTask;
use SymfonyBridgeDoctrineFormTypeEntityType;
use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentOptionsResolverOptionsResolver;
class TaskType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
// other task fields
->add('assignedTo', EntityType::class, [
'class' => Person::class,
'choice_label' => 'name',
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Task::class,
]);
}
}

它将选择所有人员,而不考虑类型。然后您可以稍后将其扩展到其他子类中!我希望这会有所帮助。

相关内容

  • 没有找到相关文章

最新更新