Just a quick post...
What seems to be missing from the DoctrineMongoDBBundle is a ParamConverter service which resolves request attributes to controller arguments by fetching a Document using the MongoDB DocumentManager. For entities, this would work:
/**
* @Route("/blog/{id}
*/
public function showAction(Post $post)
{
// $post will be the entity Post with the "id" taken from the route pattern
}
This works because of the DoctrineParamConverter, which is registered by default by the SensioFrameworkExtraBundle. But only for Doctrine ORM, and not for Doctrine MongoDB ODM. As Christophe Coevoet mentioned when someone tried to implement this missing feature, it can be added easily by yourself, without writing any PHP code, though it might not be so clear how to accomplish this. Still, the only thing you have to do is add a service to your services.xml
file:
<service id="doctrine_mongo_db_param_converter" class="Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\DoctrineParamConverter">
<argument type="service" id="doctrine_mongodb" />
<tag name="request.param_converter" converter="doctrine.odm" />
</service>
As you can see, the DoctrineParamConverter
is reusable, but it receives the ManagerRegistry for MongoDB ODM instead of the ORM.
So now, when Post
is a Document, it will be fetched by its ID, just like if it were an Entity.
Please check out the ParamConverter documentation when you don't use the default Document manager, or when the value of the Document's identifier is not in the request attribute "id".
I just tried, and I can confirm that this still works in 2018 with Symfony 4.1.
Cool, thanks for letting everyone know :)
Thank you very much for this post! Exactly what I was looking for. Works great!
If you are using .yml configuration:
doctrine_mongo_db_param_converter:
class: Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\DoctrineParamConverter
arguments: ["@doctrine_mongodb"]
tags:
- { name: "request.param_converter", converter: "doctrine.odm" }
Thanks.. It wondering and searching a long time why ParamConverter was not working .. then found your post. Thanks!
Not bad. I have some another problem with
$this->getDoctrine()
in common controller. I add
$container->setAlias('doctrine', 'doctrine_mongodb');
to my Extension file and its work fine. Converter also work fine after this. So I create PR
https://github.com/doctrine...
Your vote is welcome.
Jeremy closed my PR with good reason. So I add
true === $container->hasAlias('doctrine') ?: $container->setAlias('doctrine', 'doctrine_mongodb');
to my Extension file
Exactly what I was looking for, thanks!
Works perfectly! Thanks! :)
Seems like the service ID now needs to be
sensio_framework_extra.converter.doctrine.orm
for this to work using Sensio Bundle 2.3, otherwise it won't override the default converter.Hey Matthias,
Thanks for that post, it really helps me out. There is one thing I hope you can help me with. How do I enable the ODM param converter on Symfony 2.0? I tried using your example but Symfony couldn't find a service with that name to inject.
Thanks (:
Hi John,
I'm not sure why it would not work. Is it the "doctrine_mongodb" service that is missing?
Best regards,
But if we look inside DoctrineParamConverter, we'll see that it uses the 'entity_manager' option. But doctrine odm doesn't have entity managers, how does it work?
The "entity_manager" option only tells us that the DoctrineParamConverter was designed with the ORM in mind. The converter works for ORM and ODM, because both implement a ManagerRegistry (
Doctrine\Common\Persistence\ManagerRegistry
) - they allow for different entity and document managers (reference by name). It also works, because both registries return instances ofDoctrine\Common\Persistence\ObjectManager
when asked for a specific manager, so querying documents and entities is quite alike.