4

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

また、 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);
}

PUT /api/users/id ルートがないと Symfony が言うのはなぜですか?

編集 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}
4

2 に答える 2

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の自動ルーティングが期待どおりに機能することを確認して、コントローラーに User* s *Controller という名前を付け、ファイル User* s *Controller.php に名前を付けます。

参照: FOSRestBundle ドキュメント

フラッシュする前に persist($user) を呼び出すのを忘れていることに注意してください。ユーザー エンティティではなく EntityManager でフラッシュを呼び出すことはできません。以下の私の例を参照してください。

DependencyInjection 、symfony2 ParamConverter暗黙のリソース名定義、および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 を手動で (たとえば、バンドルの Resources/config/services.xml に) 挿入する必要があります。

@DI\Service アノテーションを使用して、コントローラーを Service として宣言します。

ここに EntityManager を注入して、@DI\Inject アノテーションを付けた $this->em を使用して、クラス全体でアクセスできるようにします。

FOSRest の @View アノテーションを使用します。アプリケーションに SensioFrameworkExtraBundle がある場合は、これを使用する前に sensio_framework_extra.view: { annotations: false } を設定することを忘れないでください。

return $this; があることを確認してください。User エンティティの setBirthdate(...) および addClub(...) 関数の最後に。

この例では [JMSDiExtraBundle のプロパティ インジェクション][3] を使用していることに注意してください。バンドルを使用するには、インストールする必要があります。

NoxLogicMultiParamBundle を使用すると、コントローラーをさらにスリム化できる場合があります。

私はここに新しいので、2つ以上のリンクを投稿することはできません...

  • Google で次のリソースを探してください。
  • NoxLogicMultiParamBundle
  • FOSRestBundle ドキュメント
  • JMSDiExtraBundle ドキュメント
于 2012-11-17T23:36:32.370 に答える
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 をサポートしていませんが、このリンクを参照してください。

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

...そしてもちろん、すべてのルートを表示するには、プロジェクト フォルダーからこれを実行します。

php app/console router:debug
于 2012-11-17T22:28:36.943 に答える