找不到PUT/api/users/id的路由

mat*_*h88 4 symfony

我试图通过从我的sencha touch 2前端调用put方法来更新我的mysql数据库中的记录.我正在调用此url/api/users/id,但我一直收到Symfony错误:

No route found for "PUT /api/users/1
Run Code Online (Sandbox Code Playgroud)

这是我在routing.yml文件中的内容

users:
    resource: "Acme\MainBundle\Controller\UsersController"
    prefix:   /api
    type:     rest
Run Code Online (Sandbox Code Playgroud)

另外,我在User*s*Controller中设置了putUsersAction

public function putUsersAction($id, Request $request)
{
    $values['birthdate'] = $request->get('birthdate');
    $values['clubid'] = $request->get('clubid');

    $em = $this->getDoctrine()->getEntityManager();

    $user = $this->getDoctrine()
        ->getRepository('AcmeMainBundle:User')
        ->find($id);

    $club = $this->getDoctrine()
        ->getRepository('AcmeMainBundle:Club')
        ->find($values['clubid']);

    $user->setBirthdate($values['birthdate']);
    $user->addClub($club);

    $em->flush();

    $view = View::create()
        ->setStatusCode(200)
        ->setData($user);

    return $this->get('fos_rest.view_handler')->handle($view);
}
Run Code Online (Sandbox Code Playgroud)

为什么Symfony告诉我没有PUT/api/users/id路由?

编辑1:路由器:调试输出

[router] Current routes
Name                     Method Pattern
_wdt                     ANY    /_wdt/{token}
_profiler_search         ANY    /_profiler/search
_profiler_purge          ANY    /_profiler/purge
_profiler_info           ANY    /_profiler/info/{about}
_profiler_import         ANY    /_profiler/import
_profiler_export         ANY    /_profiler/export/{token}.txt
_profiler_phpinfo        ANY    /_profiler/phpinfo
_profiler_search_results ANY    /_profiler/{token}/search/results
_profiler                ANY    /_profiler/{token}
_profiler_redirect       ANY    /_profiler/
_configurator_home       ANY    /_configurator/
_configurator_step       ANY    /_configurator/step/{index}
_configurator_final      ANY    /_configurator/final
get_users                GET    /api/users.{_format}
post_users               POST   /api/users.{_format}
get_clubs                GET    /api/clubs.{_format}
post_clubs               POST   /api/clubs.{_format}
put_users                PUT    /api/users.{_format}
Run Code Online (Sandbox Code Playgroud)

Nic*_*ich 7

首先,您应该调试路由并查看路由是否正确注册.您发布的路由剪辑缺少正确的意图.它应该是:

user:
    resource: "Acme\MainBundle\Controller\UserController"
    prefix:   /api
    type:     rest
Run Code Online (Sandbox Code Playgroud)

之后,您可以使用console命令调试路由:

php app/console router:debug
Run Code Online (Sandbox Code Playgroud)

此外,您可以使用grep(Unix)或findstr(Windows)来搜索路由的输出:

php app/console router:debug | grep /api
Run Code Online (Sandbox Code Playgroud)

要么

php app/console router:debug | findstr /api
Run Code Online (Sandbox Code Playgroud)

接下来确保FOSRestBundle 的自动路由按预期工作,以命名控制器User*s*Controller和文件User*s*Controller.php.

请参阅:FOSRestBundle文档

请注意,您在刷新之前忘记调用persist($ user),并且您不能在您的用户实体上调用flush,而是在您的EntityManager上调用flush.请参阅下面的示例.

通过使用DependencyInjection,symfony2 ParamConverter,隐式资源名称定义FOSRestBundle提供的@View Annotation,可以大大减少控制器的负担.

你的控制器会读到这样的东西:

<?php

namespace Acme\MainBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use JMS\DiExtraBundle\Annotation as DI;
use Acme\MainBundle\Entity\User;
use FOS\RestBundle\Controller\Annotations\View;

/**
 * @DI\Service
 */
class UserController
{

    /** @DI\Inject("doctrine.orm.entity_manager") */
    private $em;

    // ...

    /**
     * @View()
     */
    public function putAction(User $user, Request $request)
    {

        $club = $this->em
            ->getRepository('AcmeMainBundle:Club')
            ->findOneById($request->get('clubid'));

        $user
            ->setBirthdate($request->get('birthdate')
            ->addClub($club);

        // you should add some validation here 

        $this->em->persist($user);
        $this->em->flush();

        return $user;
   }

   // ...
}
Run Code Online (Sandbox Code Playgroud)

说明:

我使用了JMSDiExtraBundle的注释.您需要此捆绑包才能使它们正常工作.

否则,您应该将控制器声明为服务,并在服务容器中手动注入EntityManager(例如,在bundle的Resources/config/services.xml中).

使用@DI\Service注释将控制器声明为Service.

在这里注入您的EntityManager,以便能够使用$ this-> em和@DI\Inject注释在整个类中访问它.

使用FOSRest的@View注释.如果你的应用程序中有SensioFrameworkExtraBundle,请不要忘记在使用之前设置sensio_framework_extra.view:{annotations:false}.

确保你有$ this; 在用户实体的setBirthdate(...)和addClub(...)函数的末尾.

请注意,我在示例中使用了[JMSDiExtraBundle的属性注入] [3].必须安装捆绑包才能使用.

您可以使用NoxLogicMultiParamBundle进一步减小控制器的负担.

我不能发布超过2个链接因为我刚刚在这里...

  • 请在google上查找以下资源:
  • NoxLogicMultiParamBundle
  • FOSRestBundle文档
  • JMSDiExtraBundle文档