使用额外字段将多对多关系渲染到表单中

Sim*_*sne 9 forms symfony doctrine-orm

我想知道创建一个表单来处理与symfony2中的额外字段的多对多关系的最佳方法是什么.

举个例子,假设我想为用户创建一个通知功能.我有UserNotification实体.另外,为了能够在实体之间的多对多关系中添加额外参数,我创建了第三个实体UserNotification.额外参数指示用户是否已读取通知.

* @ORM\Entity() */
class Notification
{
    /** @Id @Column(type="integer") */
    private $id;

    /** @OneToMany(targetEntity="UserNotification", mappedBy="notification") */
    private $usernotifications;

    /** @Column() */
    private $message;

    ...
}

* @ORM\Entity() */
class User
{
    /** @Id @Column(type="integer") */
    private $id;

    /** @OneToMany(targetEntity="UserNotification", mappedBy="user") */
    private $usernotifications;

    /** @Column() */
    private $name;

    ...
}

* @ORM\Entity() */
class UserNotification
{
    /** @ManyToOne(targetEntity="User", inversedBy="usernotifications")
    private $user;

    /** @ManyToOne(targetEntity="Message", inversedBy="usernotifications")
    private $message;

    /** @Column(type="boolean") */
    private $isRead;

    ...
}
Run Code Online (Sandbox Code Playgroud)

这样我就可以获得这种数据

      User
+----+---------+
| id | name    |
+----+---------+
|  1 | John    |
|  2 | Paul    |
+----+---------+

      Notification
+----+----------------------+
| id | message              |
+----+----------------------+
|  1 | Cool stuff           |
|  2 | Lorem ipsum          |
+----+----------------------+

      UserNotification
+---------+-----------------+---------+
| user_id | notification_id | isRead  |
+---------+-----------------+---------+
|  1      |              1  |       1 |
|  2      |              1  |       0 |
|  1      |              2  |       0 |
|  2      |              2  |       1 | 
+---------+-----------------+---------+
Run Code Online (Sandbox Code Playgroud)

好了,现在问题是,如何制作一个允许向某些用户发送通知的表单?凭借经典的多对多关系,这不是问题.我有NotificationType以下内容builder:

    $builder->add('users', 'entity', array(
                'class' => 'User',
                'property' => 'name',
                'multiple' => 'true',
            ))
            ->add('message', 'text');
Run Code Online (Sandbox Code Playgroud)

但由于我必须创建中间UserNotification实体,我不知道该怎么做.谢谢你的帮助 ;)

gre*_*emo 4

我也这么做了。我的InternalMessage实体是你的Notification。在表单中,users字段未映射(property_pathis false),并且使用订阅者对其进行验证:

\n\n\n\n
public function buildForm(FormBuilder $builder, array $options)\n{\n    $builder\n        ->add(\'title\', \'text\', array(\n            \'label\' => \'Titolo *\'\n        ))\n        ->add(\'content\',  \'textarea\', array(\n            \'label\' => \'Contenuto *\'\n        ))\n        ->add(\'priority\', new PriorityType(), array(\n            \'label\' => \'Priorit\xc3\xa0 *\'\n        ))\n        ->add(\'users\', \'entity\', array(\n            \'label\'         => \'Destinatari *\',\n            \'class\'         => \'Acme\\HelloBundle\\Entity\\User\',\n            \'property\'      => \'select_label\',\n            \'multiple\'      => true,\n            \'expanded\'      => true,\n            \'property_path\' => false,\n        ));\n    ;\n\n    $builder->addEventSubscriber(new AddUsersValidationSubscriber());\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

在我的控制器中,我唯一要做的一件事(假设表单有效)是在表单模型中为每个用户创建一个InternalMessageFeedback实体(与您的相同):UserNotification

\n\n
$message = new InternalMessage();\n$form    = $this->createForm(new InternalMessageType(), $message);\n\n// ...\n\n// The sender\n$message->setUser($this->getSecurityContext()->getToken()->getUser());\n\n// Persist the inverse side\n$em = $this->getEntityManager();\n$em->persist($message);\n\n// One feedback for each user\n/** @var $user \\Acme\\HelloBundle\\Entity\\User */\nforeach($form->get(\'users\')->getData() as $user) {\n    $feedback = new InternalMessageFeedback();\n\n    // Se the message and user for current feedback\n    $feedback->setInternalMessage($message);\n    $feedback->setUser($user);\n\n    // Persist the owning side\n    $em->persist($feedback);\n\n    // Sync the inverse side\n    $message->addInternalMessageFeedback($feedback);\n}\n\n$em->flush();\n
Run Code Online (Sandbox Code Playgroud)\n\n

希望这可以帮助 :)

\n