在我开始之前,请注意我正在学习symfony,所以请记住这一点!我只是想了解它是如何工作的。 这就是我想要实现的目标:
我想用doctrine做一个实体继承的工作示例。所以这就是我的例子:
因此,在阅读了一些文档后,我决定使用Doctrine的STI(单表继承)。
家长班:
/**
* Character
*
* @ORM\Table(name="character")
* @ORM\Entity(repositoryClass="AppBundle\Repository\CharacterRepository")
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="discr", type="string")
* @ORM\DiscriminatorMap({"magician_db" = "Magician", "warrior_db" = "Warrior", "archer_db" = "Archer"})
*/
abstract class Character{
protected id;
protected name;
public function getId();
public function getName();
public function setName();
}
儿童等级1:
class Warrior extends Character{
protected armor;
public function battleShout();
}
儿童班2:
class Magician extends Character{
protected silk;
public function spellAnnounce();
}
儿童班3:
class Archer extends Character{
protected leather;
public function arrows();
}
我设法在我的数据库中创建表,并且我成功加载了我的灯具用于测试目的。我也使我的主视图工作(列出所有字符)。
我的问题: 现在我希望能够创建,编辑和使用单个表单删除列表中的特定字符。所以例如我会有一个'type'选择字段,我可以选择'warrior','magician'或'archer',然后我就可以填写所选实体的特定字段。所以,假设我在表单中选择“warrior”,然后我希望能够设置 armor property (当然还有父母)并将其保存在数据库中。
我不知道怎么做,因为我的父类是抽象的,所以我不能根据该对象创建一个表单。
提前帮助你,我真的需要它!
PS:如果有更好的解决方案/实施,请不要犹豫!
答案 0 :(得分:1)
最简单的方法是提供所有字段,并根据'类型'删除它们。值。
为此,您必须在客户端(用于显示目的)和服务器端实现逻辑(以便在您的实体中无法更改已删除的字段)。
在客户端:
在服务器端:
http://symfony.com/doc/current/components/form/form_events.html#a-the-formevents-pre-submit-event
您的表格应如下所示:
// ...
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
$form = $formFactory->createBuilder()
->add('type', ChoiceType::class)
->add('armor')
->add('silk')
->add('leather')
->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
$submittedData = $event->getData();
$form = $event->getForm();
switch($submittedData['type'])
{
case 'warrior':
$form->remove('silk');
$form->remove('leather');
break;
case 'magician':
$form->remove('armor');
$form->remove('leather');
break;
case 'archer':
$form->remove('armor');
$form->remove('silk');
break;
default:
throw new ...;
}
})
->getForm();
// ...
修改强>
要处理单表继承,您不能使用抽象类,基类必须是普通实体。
在表单中,只需将类设置为 AppBundle \ Character 。
在创建角色的控制器操作中,您必须使用以下内容启动实体:
if($request->isMethod('POST')){
// form has been submitted
switch($request->get('type'))
{
case 'warrior':
$entity = new Warrior();
...
}
}
else{
// form has not been submitted, default : Warrior
$entity = new Warrior();
}
通过编辑和删除角色,您可以直接处理角色实体。
我建议不要让用户通过编辑更改类型,请参阅Doctrine: Update discriminator for SINGLE_TABLE Inheritance