Angelo Giuffredi
Angelo Giuffredi

Reputation: 943

Troubleshooting "The controller for URI is not callable" error

I'm working on Symfony 2.3 and I declared a new route and new controller, but when I call this controller from the browser I get this error:

The controller for URI "/user/1" is not callable. in /dev.mydomain.org/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php at line 82

This is my simple route configuration:

user_homepage:
    pattern:  /user
    defaults: { _controller: UserBundle:Default:index }
    
user_show:
    pattern:  /user/{id}
    defaults: { _controller: UserBundle:Default:show }
    requirements:
        id:  \d+

And this is my very simple controller:

public function showUserAction($id)
{        
    return $this->render('UserBundle:Default:show.html.twig', array());
}

What is wrong?

Upvotes: 30

Views: 77026

Answers (10)

Mark Shehata
Mark Shehata

Reputation: 161

The same issue could happen if your env uses .env.local.php and new changes are added to env files without running composer dump-env

Upvotes: 0

R Sun
R Sun

Reputation: 1669

I would like to share my experience & how I solved it:

I was importing one bundle in an application whose routes were defined using annotations and they were importing fine in application too by using:

auth_bundle_routes:
  # loads routes from the given routing file stored in some bundle
  resource: '@XyzAuthBundle/Controller/'
  type:     annotation

But since my bundle controllers were defined using services, Symfony was showing error:

The controller for URI "/facebook/request-code" is not callable. Controller Xyz\AuthBundle\Controller\FacebookController" has required constructor arguments and does not exist in the container. Did you forget to define such a service?

I updated my bundle for routing to use routing.yaml file over annotations and referring to controllers as service::method syntax and then this error is gone.

xyz_auth.facebook_request_code:
  path: /facebook/request-code
  controller: xyz_auth.controller.facebook_controller::requestCode

Bundle routes must be imported using

auth_bundle_routes:
  resource: '@XyzAuthBundle/Resources/config/routing.yaml'

Hope this will save someone's time.

Upvotes: 0

sh6210
sh6210

Reputation: 4540

In my case, i was using symfony 2.

Prior version of symfony maintain method naming convention. Method suffix should contain Action word.

example:

in route yml file the method definition was

docudex_report_make_authorization:
pattern:  /make-authorization
defaults: { _controller: DocudexReportBundle:Default:makeAuthorization }

and in the controller the method was

public function makeAuthorization(){}

therefore i was getting the error.

After changing the method name to public function makeAuthorizationAction it worked perfectly.

Upvotes: 0

ironchicken
ironchicken

Reputation: 794

Similar to the accepted answer, if your controller is defined as a service, e.g. (in YAML):

services:
    user.default:
        class: \UserBundle\DefaultController

And your route uses this controller service:

user_show:
    pattern:  /user/{id}
    defaults: { _controller: user.default:showUserAction }
    requirements:
        id:  \d+

Then it's necessary to name the action method in full including the Action suffix, otherwise you will get the "controller ... is not callable" error.

Upvotes: 0

Wouter J
Wouter J

Reputation: 41934

The logical name UserBundle:Default:show refers to UserBunde\Controller\DefaultController::showAction you have a method called showUserAction.

Either change the method name to showAction or change the logical name to UserBundle:Default:showUser.

Upvotes: 75

itrascastro
itrascastro

Reputation: 785

Not the case here. But there is another related issue:

If you forget the 'Action' suffix all will work. But when you realized that you forget the suffix and then add it ... surprise! Same error as the OP.

The problem here is about caching

Symfony creates two file for caching urls:

  • AppDevUrlGenerator.php
  • AppDevUrlMatcher.php

If you change your action name (i.e. adding 'Action' suffix) then that cache info is obsolete.

Solution

php app/console cache:clear

Upvotes: 1

Darkland
Darkland

Reputation: 353

After big search, this worked for me:

1.- Create CRUDController

// src/Acme/DemoBundle/Controller/CRUDController.php

namespace Acme\DemoBundle\Controller;

use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Sonata\AdminBundle\Controller\CRUDController as Controller;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Inter\PimeBundle\Entity\Empresa;

class CRUDController extends Controller
{
    public function publicarAction($id)
    {
       //code here...
    }
}

2.- Create the service

# app/config/config.yml
services:
    ebtity.admin.service:
        class: Acme\DemoBundle\Admin\EntityAdmin
        tags:
            - { name: sonata.admin, manager_type: orm, group: group, label: label }
        arguments:
            - NULL
            - Acme\DemoBundle\Entity\Entity
            - AcmeDemoBundle:EntityAdmin

3.- Create the template for the action button

{# src/Acme/DemoBundle/Resources/views/CRUD/list__action_publicar.html.twig #}

<a class="btn btn-sm" href="{{ admin.generateObjectUrl('publicar', object) }}">Publicar</a>

4.- Configure route

// src/Acme/DemoBundle/Admin/EntityAdmin.php

namespace Acme\DemoBundle\Admin;

// ...

use Sonata\AdminBundle\Route\RouteCollection;

class EntityAdmin extends Admin
{
     // ...

    protected function configureListFields(ListMapper $listMapper)
    {
        $listMapper
            ->addIdentifier('name')
            ->add('engine')
            ->add('rescueEngine')
            ->add('createdAt')
            ->add('_action', 'actions', array(
                'actions' => array(
                    'publicar' => array(
                        'template' => 'AcmeDemoBundle:CRUD:list__action_publicar.html.twig'
                    )
                )
            ));
    }

    protected function configureRoutes(RouteCollection $collection)
    {
        $collection
                ->add('publicar', 
                    $this->getRouterIdParameter().'/publicar',
                    array('_controller' => 'AcmeDemoBundle:CRUD:publicar')    
                );
    }
}

5.- Clear cache

Hope it helps

Upvotes: 3

Todor Todorov
Todor Todorov

Reputation: 2541

One of the reasons for this error is that you missed to add the word "Action" after the controller's method name. If you think that your routing is OK, check the method name.

Upvotes: -1

Onshop
Onshop

Reputation: 3085

Although not relevant to the example given, this error can also be caused if the controller Action is not public

Upvotes: 23

saamorim
saamorim

Reputation: 3905

You're defining your controller function as showUserAction while in the definition your saying it is show[Action].

Either change your route configuration

user_show:
    pattern:  /user/{id}
    defaults: { _controller: UserBundle:Default:showUser }
    requirements:
        id:  \d+

or change your controller signature

public function showAction($id)
{

See if this helps

Upvotes: 4

Related Questions