Every parent controller must have `get{SINGULAR}Ac

2020-07-09 10:44发布

问题:

I have three controller named BlogController, PostController, CommentController that CommentController is sub resource of PostController and PostController sub resource of BlogController.

/**
 * @Rest\RouteResource("blog", pluralize=false)
 */
class BlogController extends FOSRestController
{
    public function getAction($blogUri)
    {
    ...
    }
}

/**
 * @Rest\RouteResource("post", pluralize=false)
 */
class PostController extends FOSRestController
{
    public function getAction($postId)
    {
    ...
    }
}

/**
 * @Rest\RouteResource("comment", pluralize=false)
 */
class CommentController extends FOSRestController
{
    public function getAction($commentId)
    {
    ...
    }
}

routing.yml

mgh_blog:
    resource: MGH\BlogBundle\Controller\BlogController
    type:     rest

mgh_blog_post:
    resource: MGH\BlogBundle\Controller\PostController
    type:     rest
    parent:   mgh_blog

mgh_blog_post_comment:
    resource: MGH\PostBundle\Controller\CommentController
    type:     rest
    parent:   mgh_blog_post

I define getAction methods, but i get following error:

[InvalidArgumentException]                                           
  Every parent controller must have `get{SINGULAR}Action($id)` method  
  where {SINGULAR} is a singular form of associated object 

Edit:

I also try to change the method's name to getCommentAction($commentId), getPostAction($postId) and getBlogAction, but it no work.

When I use @RouteResource annotations, method name must be getAction($id), otherwise it doesn't work.

When I change parent of mgh_blog_post_comment router to mgh_blog, it's working!

回答1:

That error description is awful and a big time waster because it doesn't tell you what the real problem is. Try the following:

/**
 * @Rest\RouteResource("blog", pluralize=false)
 */
class BlogController extends FOSRestController
{
    public function getAction($blogUri)
    {
    ...
    }
}

/**
 * @Rest\RouteResource("post", pluralize=false)
 */
class PostController extends FOSRestController
{
    public function getAction($blogUri, $postId)
    {
    ...
    }
}

/**
 * @Rest\RouteResource("comment", pluralize=false)
 */
class CommentController extends FOSRestController
{
    public function getAction($blogUri, $postId, $commentId)
    {
    ...
    }
}

You didn't have the correct number of arguments in the descendant controller actions. It took me two days of step debugging to figure this out.

The parent route, Blog, looks like:

/blog/{blogUri}

It will match

public function getAction($blogUri)

The child route, Post, looks like:

/blog/{blogUri}/post/{postId}

It will not match the code below because it needs two parameters. The same is true for the grandchild--which is looking for three parameters:

public function getAction($postId)

The grandchild route, Comment, looks like:

/blog/{blogUri}/post/{postId}/comment/{commentId}

The code keeps track of the ancestors of each controller. The post has 1 ancestor. When building the routes for the post controller, the code looks at the number of parameters on the 'get action'. It take the number of parameters and subtracts the number of ancestors. If the difference is not equal to one, it throws the error.

Conclusion, for each descendant, it needs to include the ID parameters of it ancestors AND its own ID. There should always be one more parameter than there are ancestors.



回答2:

Have you tried?:

class CommentController extends FOSRestController
{
    public function getCommentAction($commentId)
    {
    ...
    }
}


回答3:

Try:

public function cgetAction(Request $request)
{
    ...
}

This is my controller example:

<?php

namespace Cf\SClinicBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\Controller\Annotations\RouteResource;
use Cf\SClinicBundle\Entity\CfAcquireImage;
use Doctrine\DBAL\DBALException as DBALException;
use Doctrine\ORM\NoResultException as NoResultException;

/**
 * CfAcquireImage controller.
 *
 * @RouteResource("acquire-image")
 */
class ApiCfAcquireImageController extends FOSRestController
{
    /**
     * @var array
     */
    public $status;

    /**
     * @var
     */
    public $parameter;

    /**
     * @var
     */
    private $role_name;

    /**
     * Constructor
     */
    public function __construct()
    {

    }

    /**
     * Lists all Cf Acquire Image entities.
     *
     * @param Request $request
     *
     * @return mixed
     */
    public function cgetAction(Request $request)
    {

    }

    /**
     * Finds a Cf Acquire Image entity by id.
     *
     * @param Request $request
     * @param         $id $id
     *
     * @return array
     */
    public function getAction(Request $request, $id)
    {

    }

    /**
     * Create a new Cf Acquire Image entity.
     *
     * @param Request $request
     *
     * @return mixed
     */
    public function postAction(Request $request)
    {

    }

    /**
     * @param Request $request
     * @param         $id
     *
     * @return array
     */
    public function putAction(Request $request, $id)
    {

    }

    /**
     * Deletes a Cf Acquire Image entity.
     *
     * @param Request $request
     * @param         $id
     *
     * @return mixed
     */
    public function deleteAction(Request $request, $id)
    {

    }
}