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

时间:2012-11-17 22:14:25

标签: symfony

我正在尝试通过从我的sencha touch 2前端调用put方法来更新我的mysql数据库中的记录。我正在调用这个url / api / users / id,但我不断收到Symfony错误:

No route found for "PUT /api/users/1

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

users:
    resource: "Acme\MainBundle\Controller\UsersController"
    prefix:   /api
    type:     rest

另外,我在用户* s *控制器中设置了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);
}

为什么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}

2 个答案:

答案 0 :(得分:7)

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

user:
    resource: "Acme\MainBundle\Controller\UserController"
    prefix:   /api
    type:     rest

之后,您可以使用控制台命令调试路由:

php app/console router:debug

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

php app/console router:debug | grep /api

php app/console router:debug | findstr /api

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

请参阅:FOSRestBundle Documentation

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

通过使用DependencyInjection,symfony2 ParamConverter implicit resource name definition和FOSRestBundle提供的 @View 注释,您可以大大减少控制器的负担。

您的控制器会读到这样的内容:

<?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;
   }

   // ...
}

说明:

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

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

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

在此处注入您的EntityManager,以便能够使用$ this-&gt; em以及@DI \ Inject注释在整个班级中访问它。

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

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

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

您可以使用NoxLogicMultiParamBundle进一步减小控制器的尺寸。

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

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

答案 1 :(得分:0)

user:
    pattern:   /api/user/{id}
    defaults:  { _controller: AcmeMainBundle:User:putUsers, id: 1 }

或者您可以使用FQCN:

defaults:  { _controller: Acme\MainBundle\Controller\UserController::putUsersAction, id: 1 }

并且只匹配PUT请求使用下面的代码,虽然有些浏览器不支持PUT和DELETE,请参阅this link

user:
    pattern:   /api/user/{id}
    defaults:  { _controller: Acme\MainBundle\Controller\UserController::putUsers, id: 1 }
    requirements:
        _method:  PUT

...当然要查看所有路线,请从项目文件夹中运行:

php app/console router:debug