{"action":"created","issue":{"url":"https://api.github.com/repos/sensiolabs/SensioFrameworkExtraBundle/issues/277","labels_url":"https://api.github.com/repos/sensiolabs/SensioFrameworkExtraBundle/issues/277/labels{/name}","comments_url":"https://api.github.com/repos/sensiolabs/SensioFrameworkExtraBundle/issues/277/comments","events_url":"https://api.github.com/repos/sensiolabs/SensioFrameworkExtraBundle/issues/277/events","html_url":"https://github.com/sensiolabs/SensioFrameworkExtraBundle/issues/277","id":27045411,"number":277,"title":"Problem with converter and option route parameter","user":{"login":"ByScripts","id":19408,"avatar_url":"https://avatars.githubusercontent.com/u/19408?v=3","gravatar_id":"","url":"https://api.github.com/users/ByScripts","html_url":"https://github.com/ByScripts","followers_url":"https://api.github.com/users/ByScripts/followers","following_url":"https://api.github.com/users/ByScripts/following{/other_user}","gists_url":"https://api.github.com/users/ByScripts/gists{/gist_id}","starred_url":"https://api.github.com/users/ByScripts/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ByScripts/subscriptions","organizations_url":"https://api.github.com/users/ByScripts/orgs","repos_url":"https://api.github.com/users/ByScripts/repos","events_url":"https://api.github.com/users/ByScripts/events{/privacy}","received_events_url":"https://api.github.com/users/ByScripts/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2014-02-06T12:22:02Z","updated_at":"2015-03-31T09:27:53Z","closed_at":null,"body":"Imagine this route:\r\n\r\n    feature_product:\r\n        pattern: /category/{category}/feature-product/{product}\r\n        defaults:\r\n            _controller: MyBundle:MyController:feature\r\n            product: ~\r\n\r\nAnd this action:\r\n\r\n    /**\r\n     * @Template\r\n     */\r\n    public function featureAction(Category $category, Product $product = null)\r\n    {\r\n        // If a product has been selected\r\n        if($product instanceof Product) {\r\n            $category->setFeaturedProduct($product);\r\n            return $this->redirect(...);\r\n        }\r\n\r\n        // Else, if no product has been selected, propose a list\r\n        $featurableProducts = $category->getProducts();\r\n        return ['products' => $featurableProducts];\r\n    }\r\n\r\nNormally, calling URL `/category/23/feature-product` should set `$category` to a `Category` object with id `23`, and `$product` should be `null`.\r\n\r\nBut in fact, what happens is that:\r\n\r\n- `$category` is a `Category` object with id `23`\r\n- `$product` is a `Product` object with a `category_id` of `23`\r\n\r\nThe converter makes a `SELECT ... FROM product WHERE category_id = 23 LIMIT 1`.\r\n\r\nI don't think it's the way the converter should work."},"comment":{"url":"https://api.github.com/repos/sensiolabs/SensioFrameworkExtraBundle/issues/comments/88012967","html_url":"https://github.com/sensiolabs/SensioFrameworkExtraBundle/issues/277#issuecomment-88012967","issue_url":"https://api.github.com/repos/sensiolabs/SensioFrameworkExtraBundle/issues/277","id":88012967,"user":{"login":"TPete","id":8928006,"avatar_url":"https://avatars.githubusercontent.com/u/8928006?v=3","gravatar_id":"","url":"https://api.github.com/users/TPete","html_url":"https://github.com/TPete","followers_url":"https://api.github.com/users/TPete/followers","following_url":"https://api.github.com/users/TPete/following{/other_user}","gists_url":"https://api.github.com/users/TPete/gists{/gist_id}","starred_url":"https://api.github.com/users/TPete/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/TPete/subscriptions","organizations_url":"https://api.github.com/users/TPete/orgs","repos_url":"https://api.github.com/users/TPete/repos","events_url":"https://api.github.com/users/TPete/events{/privacy}","received_events_url":"https://api.github.com/users/TPete/received_events","type":"User","site_admin":false},"created_at":"2015-03-31T09:27:53Z","updated_at":"2015-03-31T09:27:53Z","body":"@ByScripts \r\n**Tl;dr** You can work around this by using the ParamConverter annotation for the optional parameter and explicitly listing the mapping between the route parameters and the entity property. Something like this:\r\n\r\n@ParamConverter(\"product\", class=\"YourProduClass\", options={\"mapping\": {\"product\": \"id\"}})\r\n\r\nThe DoctrineParamConverter will first try to find the entity by id (see apply method). If this fails (as there is not id in your example) it will fall back to *class repository->findOneBy()* (see findOneBy).\r\nIf you do not provide a mapping the DoctrineParamConverter will try mappings as *parameter* => *parameter* for **all** route parameters. In your example it will look for fields named *product* and *category* in your product class. If such fields happens to exist, it will then call *findOneBy* with this mapping. So if your *product* class has a property named *category* it will fetch a product with category 23.\r\n\r\nI hope this made some sense, just have a look at the *apply* and *findOneBy* method of the DoctrineParamConverter."}}