一对多的属性,具有Symfony 3 / Doctrine形式的表单

朱罗0sS

这是问题所在:

我有3个班级的模型

  • 人工作
  • 工作

一个人可以有多个工作,任何工作-人际关系都可以具有“ date_start”属性,“ date_end”和“ comment”。因此,我使用持有这些属性的可联接(person_job)构建了该模型,并在2个名为person和job的manyToOne属性上建立了关系(通过教义注释生成)

Person属性看起来像:

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

/**
* @var string
* @ORM\Column(name="firstname",type="string",length=255,nullable=true)
*/
private $firstname;
/**
* @var bool
* @ORM\Column(name="active", type="boolean")
*/
private $active;

作业属性如下所示:

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

person_job看起来像这样:

/**
* @ORM\ManyToOne(targetEntity="...\Person")
* @ORM\JoinColumn(nullable=false)
*/
private $person;

/**
* @ORM\ManyToOne(targetEntity="...\Job")
* @ORM\JoinColumn(nullable=false)
*/
private $job;

/**
* @var string 
* @ORM\Column(name="comment",type="string",length=255,nullable=true)
*/
private $comment;

/**
* @var \DateTime
* @ORM\Column(name="startdate",type="datetime")
*/
private $datestart;

/**
* @var \DateTime
* @ORM\Column(name="enddate",type="datetime")
*/
private $dateend;

现在,我想为我的“人员”构建一个表单,从中可以在列表中选择作业,并添加(如果需要)date_start,date_end或与此作业相关的注释。我的FormBuilder对于“ Person”如下所示:

$builder
  ->add('name')
  ->add('firstname')
  ->add('jobs',Job::class,array('label'=>'Job'));

这失败了。我的Person类没有“职位”属性。那么,我该如何实现这些目标?我是否必须添加一个带有“ tombyBy”声明的,具有oneToMany关系的Jobs属性?

这些在学说上的关系仍然让我感到困惑,我是symfony的新手,我在互联网上看了一下,但还没有找到合适的解决方案/示例...

感谢您的阅读/帮助

流明

您遇到了Symfony表格中最困难的问题之一。幸运的是,这里有一些很好的文档。让我总结一下重要步骤。

您是对的:如果要从Person的角度操纵该实体,则Person实体需要了解其与PersonJob的关系。因此,您需要添加一个属性:

// src/AppBundle/Entity/Person.php
/**
 * @ORM\OneToMany(targetEntity="PersonJob", mappedBy="person")
 */
private $personJobs;

public function __construct()
{
    $this->personJobs = new \Doctrine\Common\Collections\ArrayCollection();
}

然后您将拥有表单类型

// src/AppBundle/Form/PersonType.php
$builder
    ->add('name')
    ->add('firstname')
    ->add('personJobs', CollectionType::class, array(
        'entry_type'   => PersonJobType::class,
        'allow_add' => true,
    )
;

注意personJobs字段的类型由于一个人可以有很多PersonJob,因此您需要一种可以处理集合的表单类型。这是内置功能的目的CollectionType(请查看其文档!)。您还需要表单类型PersonJobType,以便CollectionType知道如何构建子表单:

class PersonJobType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('comment')
            ->add('datestart', DateTimeType::class)
            ->add('dateend', DateTimeType::class)
            ->add('job') // requires Job::__toString() to be defined!
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\PersonJob'
        ));
    }
}

出于调试目的,将控制器更改为

 public function testAction()
 {
    $person = new Person();
    $form = $this->createForm(PersonType::class, $person);
    $form->add('submit', SubmitType::class);

    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        print '<pre>';
        var_dump($form->getData());
        die();
    }

    return $this->render('default/index.html.twig', [
        'form' => $form->createView(),
    ]);
}

现在继续复制和粘贴,从树枝和JavaScript代码,添加和删除项目(你必须做出细微的变化,如更换form.emailsform.personJobs)。

表格

表格看起来像

只是带有“添加另一个PersonJob”链接的Person表单

第一步

添加一个PersonJob:

添加一个PersonJob

添加令人讨厌的PersonJob:

添加另一个PersonJob

收到的数据

提交表单,然后查看输出var_dump

object(AppBundle\Entity\Person)#247 (5) {
  ["id":"AppBundle\Entity\Person":private]=>
  NULL
  ["name":"AppBundle\Entity\Person":private]=>
  string(12) "Charles Dude"
  ["firstName":"AppBundle\Entity\Person":private]=>
  string(7) "Charles"
  ["active":"AppBundle\Entity\Person":private]=>
  bool(true)
  ["personJobs":"AppBundle\Entity\Person":private]=>
  object(Doctrine\Common\Collections\ArrayCollection)#248 (1) {
    ["elements":"Doctrine\Common\Collections\ArrayCollection":private]=>
    array(2) {
      [0]=>
      object(AppBundle\Entity\PersonJob)#962 (6) {
        ["id":"AppBundle\Entity\PersonJob":private]=>
        NULL
        ["comment":"AppBundle\Entity\PersonJob":private]=>
        string(19) "Something important"
        ["datestart":"AppBundle\Entity\PersonJob":private]=> 
        object(DateTime)#1088 (3) { … }
        ["dateend": …] => …
        ["person":"AppBundle\Entity\PersonJob":private]=>
        NULL
        ["job":"AppBundle\Entity\PersonJob":private]=>
        object(AppBundle\Entity\Job)#1171 (2) {
          ["id":"AppBundle\Entity\Job":private]=>
          int(2)
          ["name":"AppBundle\Entity\Job":private]=>
          string(5) "Job 2"
        }
      }
      [1]=> …
  }
}

还有两件事要做:

  1. person嵌套PersonJob实体属性正确设置为新的(但尚未持久)人员。

  2. PersonJob通过调用将新实体告知Doctrine $em->persist(…)

相关文件:

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

symfony3:为具有多对一关系的列的实体创建表单

当表单具有实体类型时,Symfony3多对多现实

在MongoDB中定义具有不同关系的3个模式(多对多,一对多...)

在 SQL Server 中加入具有一对多和多对多关系的 3 个表

Symfony 3形式多对多

具有一对多的Doctrine ArrayCollection会引发错误

Symfony 4表单使用具有附加属性的联接表进行多对多

创建子表单并将其以现有形式附加到symfony 3中

Symfony 3 一对多:如何在坚持反面时将反面添加到拥有面

Spring 3 MVC:动态表单中的一对多(在创建/更新时添加/删除)

TYPO3 8.7中具有表单框架的多列表单

Symfony 3.x-多对多额外字段表单集合

Doctrine2挑战,我有一个一对多,但没有多个

3 个表连接一对多

具有文件类型字段editAction的Symfony 3表单集合实体

Symfony形式(作为具有Doctrine的独立组件)EntityType不起作用

“一对多” Rails表单创建

形式一对多-背包laravel

Symfony3 表单类型和多对多关系

Symfony 3表单多文件上传问题

从 Doctrine 实体 (Symfony3) 中获取所有值

Symfony 3多层嵌套表单

Symfony 2多文件上传嵌入表单的另一种形式

使用 Doctrine 的具有一对多关系和多个条件的 QueryBuilder

Laravel具有一对一关系的表单绑定

具有一对一关系的Rails 4嵌套表单

如何从具有两个一对多关系的3个表中读取数据

Symfony Doctrine 3 表之间的关系

Symfony 3 的 Doctrine Fixtures 的多个文件