Symfony Best Practice - 実践編 Chapter5-3-

前回

hanahirodev.hatenablog.com

いじった結果は随時GitHubにあげていきます。


ParamConverterを使う

BlogControllerでParamConverterを使う場合と、使わない場合の書き方の比較をしてみる。

変更前は、ParamConverterを使っている。

// BlogController.php
/**
     * @Route("/comment/{postSlug}/new", name="comment_new")
     * @Method("POST")
     * @Security("is_granted('IS_AUTHENTICATED_FULLY')")
     * @ParamConverter("post", options={"mapping": {"postSlug": "slug"}})
     */
    public function commentNewAction(Request $request, Post $post)

そもそもParamConverterは何をしてくれるかドキュメントで確認。 ParamConverterにはDoctrine ConverterとDateTime Converterの2種類があって、今回はDoctrine Converterを使ってるということがわかった。

Doctrine ConverterによりpostSlugというパラメーターでコントローラーに渡されてきた値を、$postslugマッピングさせて値の比較をしている。 ということは、slugというパラメーターでコントローラーに渡してあげればParam Converte使わなくても動きそうなので、以下のように書き換えてみる。

// BlogController.php
/**
     * @Route("/comment/{slug}/new", name="comment_new")
     * @Method("POST")
     * @Security("is_granted('IS_AUTHENTICATED_FULLY')")
     */
    public function commentNewAction(Request $request, Post $post)

パラメーターはTwig側で設定されてるので、Twigの方も書き換える。

// /app/Resources/views/blog/_comment_form.html.twig
{{ form_start(form, { method: 'POST', action: path('comment_new', { 'slug': post.slug }) }) }}

これでParamConverterを使わなくても動くようになった。 ただし、ドキュメントによると以下の条件の下で実現してるそうな。

  • ルーティングに{id}が設定されている場合は、find ()メソッドで主キーをフェッチ。
  • ワイルドカードに指定されているプロパティで、エンティティにあるプロパティをfindOneBy()でフェッチ。

上記挙動はoptionsを指定すると変えられる。

複雑なことをしたい場合は、Entityクラスに対応するRepositoryクラスを作って、@EntityアノテーションでRepositoryクラスのメソッドを指定して検索させることができる。

感想

「EntityとRepositoryの違いって何?」と思っていた時期があったけど、この挙動を知ると役割の違いが明確化できていいな。 Best Practiceでは、Twigをデザイナーさんに触ってもらうことを考えているので、Entityでの名称を画面に持ち込みたくない(意識させたくない)場合とかに使ってねという意図を感じなくもない。