BLOGカルテットコミュニケーションズ開発部ブログこの記事は公開されてから1年以上経過しています。情報が古い可能性がありますのでご注意ください。Converterについての基本的な動作をケース・スタディとして確認したいと思います。前提あるアプリケーションにおいて以下の前提が成り立つとします。ユーザは一意のnameという属性を持つ。ユーザは複数の画像ファイルを保有でき、そのうちひとつをプロフィール画像として指定できる。ユーザは住所情報を登録し、異なるユーザが同一の住所を登録することもできる。このとき、エンティティを反映したDBのテーブルが以下のようだとします。/1)を実装してみます。おける"user"は該当コントローラのアクションメソッドの引数名、class=で指定されているクラスはコンバート対象のクラスとなります。/1というリクエストを送った場合には、Routeに指定された{id}をキーにリソースを特定しAppBundle:Userオブジェクトを生成してgetUserByIdActionメソッドの$userとして注入されます。/2というリクエストを送った場合には、user.id=2のユーザは存在しないのでステータスコード404のHTTPレスポンスが返ります。このリクエスト時に走っているクエリは以下です。プライマリキーで探索しているのがわかりますね。1;なお、コントローラアクションのシグネチャとしてタイプヒンティングを採用することで@ParamConverterアノテーションは省略することができます。コードがシンプルになりますね。してみるルートリソースの指定パラメータ名を{id}から{user_id}にしてみます。コーディング時の視認性の良さがメリットですかね。いうエラーメッセージが表示されました。この定義では情報が足りないようです。ここで{user_id}がUserエンティティのプライマリキーidであることを教えてやります。$user){}これで正常に取得できました。/user_1)を実装してみます。URLに数字のIDが指定されているよりもヒューマンフレンドリですよね。$user){}正常に取得できました。ここで走っているクエリは以下です。idを指定した場合とは異なっています。ここで仮に住所を指定することにしてみます。$user){}user_1の情報が取得できました。ここで走っているクエリは以下です。1;しかしそもそもこれは設計がおかしいですね。user_1もuser_2も住所1に住んでいます。どちらのユーザかを特定できる情報はURL上にはありません。$users)といった感じになるべきです。設計がおかしいことをParamConverterが「Userエンティティはaddressプロパティではユニークじゃないよ!」とエラーで教えてくれると良いのですがそのような仕組みになっていません。これからもわかるようにid以外をキーとする際にはユニークになるものを指定するように設計には注意したいですね。してみるルートリソースの指定パラメータ名を{name}から{user_name}にしてみます。{id}のときと同様ですので別名がどの属性を示すかを定義してやる必要がありますね。$user){}失敗です。information.と表示されてしまいました。$user){}mappingオプションを用いて「Routeの{user_name}はUserエンティティのname属性にマップされますよ」と教えてやる必要があります。"user_id"})として指定しましたよね。"user_name"})では動作しないのでしょう?ここで"id"というのはUserエンティティのid属性を意味するのではなく、あくまでidentityという意味として考えたほうがよさそうです。「Userエンティティを特定するプライマリキー(=id)として{user_id}を使いますよ」という宣言だったわけです。keyという文言があるのでidオプションではなくpkオプションとしたほうが混乱しなくて良さそうだなと感じました。/users/user_1/images/1)を実装してみます。found.というメッセージとともに404が返ってきます。user_1のユーザも居ますしid=2の画像もあります。?この際に走っているクエリは以下です。1;{name}も{image}もUserエンティティの特定のために使用されていることがわかります。found.となりやっぱりだめですね。この際に走っているクエリは以下。さきほどと変わりありません。1;ここでmappingオプションを指定してやります。$image){}うまくいきました。走っているクエリは以下。2;なお、以下のようにImageエンティティに関する記述はなしでも動きます。$image){}また、以下のようにexcludeオプションとしてエンティティ特定に使用しないパラメータを指定することもできます。この例の場合は上記と下記は結果としては同義になりますね。Converterでは以下の順でリソースの取得をトライします。{id}がRouteに指定されていたら、この値を用いてDBよりプライマリキーにより探索オプションでidが指定されていたら、この値を用いてDBよりプライマリキーにより探索どちらも適用されない場合には、Routeで指定されているパラメータを用いてDBよりリソースを1件取得これらの動作を当エントリでは失敗ケースを含めて例示してみました。参考にしていただければ幸いです。Converterでは今回の例で出てこなかった以下のオプションも存在します。詳細はドキュメントを御覧いただき活用いただければと思います。TtskchTheme。