【问题标题】:Symfony3: Binding Form to Entity ClassesSymfony3:将表单绑定到实体类
【发布时间】:2017-09-19 20:20:01
【问题描述】:

我正在使用内置 Symfony3 服务创建表单:
1) 在 AppBundle\Form 中创建新类,扩展 AbstractType
2)在我的控制器中创建一个表单对象(使用createForm())
3)将该对象直接推到树枝层(createView())

在我的实体方向上,我有两个类,已经通过 ORM 映射到数据库。 第一个是User,第二个是UserAttribute。 User 通过 OneToMany 注释与 UserAttribute 相关联。关系如下:


class UserAttr
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @ORM\Column(type="integer")
     */
    private $id;
    /**
     * @ORM\ManyToOne(targetEntity="User", inversedBy="userAttr" )
     * @ORM\JoinColumn(nullable=false)
     */
    private $user;

从User 方面:

class User
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @ORM\Column(type="integer")
     */
    private $id;
    /**
     * @ORM\OneToMany(targetEntity="UserAttr", mappedBy="user")
     * @ORM\JoinColumn(nullable=false)
     */
    private $userAttr;

当我添加新字段(使用$builder->add())时,如果它们与User 类属性相关联,则一切正常。但是如果我对UserAttribute 属性做同样的事情 - symfony 找不到该属性的 get/set 方法。我知道 - 我可以通过 class User extends UserAttribute 修复它,但可能不是重点。 Symfony 必须有另一种解决方案,可能我错过了什么。

感谢您的宝贵时间!

// SOLVED | there should be defined an EntityClassType as below:
$builder->add('credit',EntityType::class,array(
                'class' => UserAttr::class
            ));

【问题讨论】:

  • 你们的关系怎么样?许多User 与单个UserAttribute 相关联,反之亦然?
  • 感谢您的反馈,我对代码进行了一些更改并在上面进行了更新。现在我有了:User--->OneToMany--->UserAttr,和反面 UserAttr--->ManyToOne--->User
  • 您想从用户表单中添加/修改关联UserAttr 属性的数量吗?
  • 不完全是,我只是想在我的表单中添加名为 credit 的新字段(这是 UserAttr 属性,而不是 User )。我可以使用添加的“信用”字段呈现该表单,但在提交后出现新错误:Neither the property "credit" nor one of the methods "getCredit()", "credit()", "isCredit()", "hasCredit()", "__get()" exist and have public access in class "AppBundle\Entity\User".
  • 感谢您抽出宝贵时间 Jeet,我找到了解决方案,并且已经更新了我上面的帖子。

标签: php forms symfony orm frameworks


【解决方案1】:

您有来自User 实体的One-To-Many 与UserAttr 的关联。因此,一个用户可能有多个信用。

选项 1:

考虑到这一点,你必须在 UserFormType 中使用collection 字段类型,这个过程有点冗长。

$builder->add('userAttr', CollectionType::class, array(
    'label' => false,
    'allow_add' => true,
    'allow_delete' => true,
    'entry_type' => UserAttrType::class
));

然后创建另一个 FormType :UserAttrType 来表示 UserAttr,您可以将 credit 字段作为来自 UserAttr 的属性。

$builder
    ->add('credit', TextType::class, array(
        'label' => 'Credit',
    ))

这样,表单将相应地加载和提交,信用值也将在用户表单更新时更新。这是collection docs 的链接。这是embed a collection form的方法。

选项 2:

但是,如果您想进一步简化它,请将mapped = false (doc) 添加到credit 字段。这将忽略当前错误。但是,您必须手动从Form 对象中收集credit 值,并在提交处理程序中将值设置为适当的UserAttr 对象。

希望对你有帮助!

【讨论】:

  • 感谢您的帮助,但给出的错误告诉我们一些不同的事情。由于集合类型没有问题,否则应该建议我实现__toString() 方法或其他方法。即使我将关系从 ManyToOne/OneToMany 更改为 OneToOne,错误仍然会出现。
  • 是的,这很正常。您所要做的就是在UserAttr 中添加一个__toString() 魔术函数并返回任何属性来识别它。可能是credit。
  • Jeet,我之前写过给定的错误是因为 Symfony 没有看到 getCredit() 方法。当我想在我的控制器函数中 if ($form->isSubmited()){ dump($form->getData()} 时,symfony 试图找到 getCredit() 方法并且找不到。这是因为该方法不在User 类中(在UserAttr 类中实现)。问题是 - 如何在不添加 class User extends UserAttr 的情况下解决它。我正在看另一个教程,并且在没有extends 的情况下实现了它,但我无法弄清楚它是如何完成的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-12
  • 1970-01-01
  • 1970-01-01
  • 2018-12-31
  • 2010-11-26
  • 1970-01-01
相关资源
最近更新 更多