当我在 FOS Rest Bundle 中有多级子资源时,每个父控制器都必须有 `get{SINGULAR}Action($id)` 方法

Every parent controller must have `get{SINGULAR}Action($id)` method when i have multi level sub resource in FOS Rest Bundle

我有三个名为 BlogControllerPostControllerCommentController 的控制器,其中 CommentControllerPostControllerPostController 子资源的子资源共 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

我定义了 getAction 方法,但出现以下错误:

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

编辑:

我也尝试将方法的名称更改为 getCommentAction($commentId)getPostAction($postId)getBlogAction,但是没有用。

当我使用@RouteResource注解时,方法名必须是getAction($id),否则不起作用

当我将 mgh_blog_post_comment 路由器的父级更改为 mgh_blog 时,它工作正常!

你试过了吗?:

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

尝试:

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

这是我的控制器示例:

<?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)
    {

    }
}

那个错误描述很糟糕而且很浪费时间,因为它没有告诉您真正的问题是什么。尝试以下操作:

/**
 * @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)
    {
    ...
    }
}

您在后代控制器操作中没有正确数量的参数。我花了两天的步骤调试才弄明白。

父路由 Blog 看起来像:

/blog/{blogUri}

它将匹配

public function getAction($blogUri)

子路由,Post,看起来像:

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

它将匹配下面的代码,因为它需要两个参数。孙子也是如此——它正在寻找三个参数:

public function getAction($postId)

孙子路线,评论,看起来像:

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

代码跟踪每个控制器的祖先。 post 有 1 个祖先。在为 post 控制器构建路由时,代码会查看 'get action' 上的参数数量。它采用参数的数量并减去祖先的数量。如果差异不等于 1,则会抛出错误。

结论,对于每个后代,它需要包括它祖先的ID参数和它自己的ID。应该总是比祖先多一个参数。