Skip to main content

Symfony2 choice list type for MongoDB backed forms

A couple of days ago, I had to implement a select field representing a one-to-one MongoDB relationship in one of my Symfony2 forms. Having spent some time reading the documentation, I decided to use the entity form field type for this purpose.

class AcmeFormType extends AbstractType
{
    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder
            ->add('parent', 'entity', array(
                'class' => 'Acme\MyBundle\Document\MyDocument',
                'property' => 'name',
                'label' => 'Parent',
                'empty_value' => 'Root'
            ));
     }
}

And I got presented with this exception:

Class Acme\MyBundle\Document\MyDocument is not a valid entity or mapped super class. 

I realized Symfony2 was trying to load the necessary class using the default entity manager defined by the Doctrine ORM and failing utterly. After digging through the code, I found out what I was looking for inside the vendor/bundles/Symfony/Bundle/DoctrineMongoDBBundle/Form/Type/DocumentType.php class. This class is the "entity" type equivalent for MongoDB backed forms. It's alias is document instead of entity, and it is registered into the service container with the usual tag/name/alias combination as can be seen in the service configuration XML snippet below.

src/vendor/bundles/Symfony/Bundle/DoctrineMongoDBBundle/Resources/config/mongodb.xml

<service id="form.type.mongodb_document" class="SymfonyBundleDoctrineMongoDBBundleFormTypeDocumentType">
    <tag name="form.type" alias="document" />
    <argument type="service" id="doctrine.odm.mongodb.document_manager" />
</service>

Long story short, if you are using MongoDB as your backend, your forms must use the document type for your choice lists.

class AcmeFormType extends AbstractType
{
    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder
            ->add('parent', 'document', array(
                'class' => 'Acme\MyBundle\Document\MyDocument',
                'property' => 'name',
                'label' => 'Parent',
                'empty_value' => 'Root'
            ));
     }
}

The configuration for document choice lists is the same as entity choice lists. See http://symfony.com/doc/current/reference/forms/types/entity.html for more information.

Comments

  1. Hey thanks for this. This seems to be exactly what I am looking for. However I am using Yaml instead of XML for configuration and can't work out how to convert your mongodb.xml to my config.yml. Would you be able to convert or provide a yaml equivalent?

    ReplyDelete
    Replies
    1. Kevin, the mongodb.xml file referenced above is provided by the DoctrineMongoDBBundle. You are not supposed to change it or convert it into YAML. I just included it in my article for reference purposes.

      Delete

Post a Comment

Popular posts from this blog

Securing Symfony2 REST services with FOSOAuthServerBundle

Overview In my previous article, I wrote about setting up a Symfony2 REST service using FOSRestBundle. However, this REST service was behind a firewall protected by a generic form_login provider. Not really ideal if you wish to open your REST API to other applications. So in this article, I will try to explain how to set up FOSOAuthServerBundle to protect your REST API methods using OAuth2. Before we start getting into the gritty details, it is a good idea to have a look at the official OAuth2 documentation . Let's begin... FOSOAuthServerBundle Installation You have to install v1.1.0 of FOSOAuthServerBundle if you are using Symfony 2.0.x. If not, see the docs . First, add the following entries to your deps file: [FOSOAuthServerBundle] git=git://github.com/FriendsOfSymfony/FOSOAuthServerBundle.git target=bundles/FOS/OAuthServerBundle version=origin/1.1.x [oauth2-php] git=git://github.com/FriendsOfSymfony/oauth2-php.git Run the vendors script to install these...

Adding post-login logic to FOSUserBundle

Having finally figured out how to use FOSUserBundle in my project, I decided to keep track of all logins next. The implementation turned out to be a breeze thanks to Symfony2's security listener mechanism. As usual, the first step is to create a MongoDB document for this purpose. This is a very simple document that contains a user's id, session id, IP address, and login date. src/Acme/UserBundle/Document/LoginHistory.php namespace Acme\UserBundle\Document; class LoginHistory { protected $id; protected $userId; protected $sessionId; protected $ip; protected $createdAt; /** * Get id * * @return custom_id $id */ public function getId() { return $this->id; } /** * Set userId * * @param int $userId */ public function setUserId($userId) { $this->userId = $userId; } /** * Get userId * * @return int $userId */ public function getUserId...

Symfony 2 + DoctrineMongoDBBundle + FOSUserBundle Tutorial

It's been a while I have not added an entry to my blog. I have been busy playing with Symfony 2, MongoDB, and FOSUserBundle for a while now so here is a tutorial to integrate Symfony 2, MongoDB, and FOSUserBundle. Objectives * Install DoctrineMongoDBBundle * Install FOSUserBundle * Create user model ** Utilize groups ** Add additional properties to user model * Create customized registration form and handler At this point I am going to assume that you have a running Symfony 2 and MongoDB installation in place already and a basic understanding of how to configure Symfony 2 services. I will also exclude view related steps from this tutorial. Setting Up DoctrineMongoDBBundle Add the following to your deps file: [doctrine-mongodb] git=http://github.com/doctrine/mongodb.git [doctrine-mongodb-odm] git=http://github.com/doctrine/mongodb-odm.git [DoctrineMongoDBBundle] git=http://github.com/symfony/DoctrineMongoDBBundle.git target=/bundles/Symfony/Bundle/Doctrin...