如何动态 select EntityManager 与 Symfony2 Form 上的 ManyToMany 一起使用

How to dynamically select EntityManager for use with ManyToMany on Symfony2 Form

我有一个 Symfony2 包,我在其中使用基于子域的 EntityManagers 的动态选择以及用于常规设置的固定 EM 等。例如,用户登陆 dev.mydomain.com 并显示带有一个登录屏幕,该屏幕从包含站点标题、颜色等的 default 数据库中提取信息。然而,登录脚本引用包含该子域的用户和数据的 dev 数据库。同样,当登录 other.mydomain.com 时,登录引用 other 数据库。这一切都很好,并且用户根据其适当的数据库进行了验证。

我遇到的问题是当我使用 Symfony 的表单系统创建 "new user form" 时。如 The Book 所述,我对用户角色使用多对多关系,但找不到指定使用哪个 EntityManager 的方法,导致它查找针对 default EntityManager 的关系。

Controller/UserController.php

public function addAction(Request $request) {

    $us = new User();

    // ORM Connection name stored in session from the login screen
    $em = $this->getDoctrine()->getManager(
        $request->getSession()->get('database')
    );

    $form = $this->createForm(
        new UserType($em), $us
    );

    return $this->render(
        'MyBundle:User:create.html.twig',
        array( 'form' => $form->createView() )
    );
}

Entity/User.php

/**
 * @var string
 *
 * @ORM\ManyToMany(targetEntity="Role", inversedBy="users", cascade={"persist"})
 */
private $roles;

config.yml

doctrine:
  dbal:
    connections:
        default:
            driver:   "%database_driver%"
            host:     "%database_host%"
            port:     "%database_port%"
            dbname:   "%database_name%"
            user:     "%database_user%"
            password: "%database_password%"
            charset:  UTF8
        dev:
            driver:   "%dev.database_driver%"
            host:     "%dev.database_host%"
            port:     "%dev.database_port%"
            dbname:   "%dev.database_name%"
            user:     "%dev.database_user%"
            password: "%dev.database_password%"
            charset:  UTF8
orm:
  default_entity_manager: default
  auto_generate_proxy_classes: "%kernel.debug%"
  entity_managers:
    default:
        connection: default
        mappings:
            MyBundle: ~
    dev:
        connection: dev
        mappings:
            MyBundle: ~

有没有办法将指定的 EntityManager 传递给 createForm 或 FormBuilder 以供 built-in ManyToMany ORM 注释使用?表单正常工作,将用户添加到所需的 EntityManager——只是 Roles 字段仍在引用 default.

Form/UserType.php 文件中使用的 FormBuilder 具有 add() 方法,允许添加实体的组件。 add() 方法可以将选项数组作为第三个元素。这些选项之一是 em:

->add('roles', 'entity', array(
         'class'=>'MyBundle:Role',
         'property'=>'name',
         'em'=>$options['em'],
         'multiple'=>true
      ))

我能够通过 Controller/User 中的 createForm() 方法将动态确定的实体管理器传递到文件中。php 可以从上面的选项数组访问:

$form = $this->createForm(
           new UserType($em), $us, array('em'=>$em)
        );

最后,我通过将实体管理器包含在 Form/UserType 中的 setDefaultOptions() 中来确保实体管理器是必需的。php:

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setRequired(array('em'));

    $resolver->setDefaults(array(
        'em' => null
    ));
}

在执行此操作时,我表单中的 ManyToMany Roles 字段从正确的实体管理器中提取并保留到正确的实体管理器。