Может быть, вы можете попробовать следующее:
В идеале, я думаю, вы хотите поделиться информацией между Customer
и Supplier
. Таким образом, мы могли бы ввести новый родительский класс, например, Person
(я не знаю, какую ответственность они несут, поэтому мы возьмем наиболее "общее" имя класса c) и используем Doctrine отображение наследования :
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="discr", type="string")
* @ORM\DiscriminatorMap({
* "customer" = "Customer",
* "supplier" = "Supplier"
* })
*/
abstract class Person
{
//... Fields, traits, embeddables...
/**
* A common attribute between our child classes
* protected to respect encapsulation
*
* @ORM\Column(type="text")
*/
protected $name;
/**
* Here we define the general link to a task. It will be inherited by child classes
*
* @ORM\OneToMany(targetEntity="App\Entity\Task", mappedBy="assignedTo")
*/
protected $tasks;
// public getters/setters...
}
Я думаю, Стратегия наследования таблиц классов подойдет вам здесь, так как вы хотели бы добавить больше объектов позже. Таким образом, мы можем уважать принцип Открыто-закрыто и позже добавить больше дочерних классов вместо изменения логики c только в одном классе.
Также я сделал Person
абстрактный класс, так как мы обычно хотим иметь дело с Customer
или Supplier
экземплярами. Но в зависимости от того, что вам нужно, может быть, вы можете удалить ключевое слово abstract
. В этом случае вам нужно будет включить Person
в карту дискриминатора.
Конечно, теперь Customer
и Supplier
должны оба расширять Person
:
//...
class Customer extends Person
//...
//...
class Supplier extends Person
//...
Не забудьте удалить общие поля (например, id
) из дочерних классов, теперь они будут унаследованы от Person
Итак, в Задаче , вы можете определить отношение ManyToOne
к Person
:
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Person", inversedBy="tasks")
*/
private $assignedTo;
Наконец, для вашей формы задачи, давайте составим список выбора с именами всех людей:
<?php
namespace App\Form;
use App\Entity\Person;
use App\Entity\Task;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
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,
]);
}
}
Он выберет всех людей, независимо от их типа. Затем вы можете расширить его позже с другими дочерними классами! Я надеюсь, что это поможет.