Laravelの複数パラメータのルーティングについて

ブログの更新自体がものすごく久しぶりです。

 

最近ではプログラミングの勉強をしています。

主にLaravelというphpのフレームワークの勉強ですね。

 

ここで僕はルーティングというものが良く分からずに苦戦しています。特にパラメータが複数URIに含まれているものについてはちんぷんかんぷんです。

例として挙げるとこんなもの。

Route::delete('cart={cart}/{item}’, [CartCobtroller::class, 'destroy’])->name('carts.destroy’);

{cart} {item} と複数のパラメータが必要なのですが、これらがビューやコントローラなどを介してどのような受け渡し方をされているのかがさっぱり分からないのです。

 

そんなLarabelのDELETEルーティングの書き方について、ざっくりとしたまとめを自分用の備忘録としてアウトプットしてみます。他のHTTPメソッドについてはまた別の機会にでも。

 

今回の動作の目的

まずはこのルーティングで何をしたいのかを明確にしておきます。

製作物はAmazonやRakutenを超簡易的にしたWebアプリ。商品をカートに入れたり戻したり、それに伴って商品の在庫数が増減します。

 

そこでCartコントローラのdestroyメソッドにて、

・cartインスタンスの削除

・削除された分のアイテムの在庫を増やす

この2つを実装したいのです。

 

コントローラを見てみよう

まずはコントローラの確認です。

 

変更を加えるモデル名は必須

変更を加えるモデルは登場不可欠です。つまり今回の例では削除するインスタンスを持っている Cartモデル と、削除後の在庫数を調整する Itemモデル の存在は必要不可欠です。

このためdestroy()アクションの引数には必ずこれらを入れる必要があります。

 

public function destroy(Cart $cart, Item $item) {

(略)

ここでモデル名をアクションの引数に入れた際には、同時に何かしらの名前でインスタンスを入れておく必要があります。

一般的にはCartモデルに対してであれば $cart, Itemモデルであれば $item になります。Unkoモデルであれば $unko になるでしょう。

 

インスタンス名はなんでもいい

ただし、このインスタンス名はなんでも大丈夫っぽいです。

Cartモデルに対して $unko とすることもできますし、Itemモデルに対して $debu などと設定してしまうこともできてしまうのです。

つまり以下のような書かれ方でも普通にプログラムが動くということです。

public function destroy(Cart $unko, Item $deb){

(略)

Cartモデルに対して $unko, Itemモデルに対して $deb となっています。

 

アクションの引数に入れることで紐づけされる

先ほどのコードのようにCart と $unko, そして Item と $deb をそれぞれアクションの引数に設定したことにより、Larabel側では自動でこれら(モデル名とインスタンス名)の紐づけがされます。

Cartモデル のインスタンスが $unko, そして Itemモデルのインスタンスが $deb ということになりました。

つまり $unko->name などと書けば自動で「Cartsテーブル の nameカラム の値だな」と判断されて、Cartsテーブルとやりとりをしてくれるようになるのです。

実に自由で素晴らしいですね。

 

ルーティングのパラメータ値に注意

ここまでだけを見ると自由で素晴らしいように見えるのですが、自由にインスタス名を設定し続けるとルーティング時にややこしいことになります。

すなわち上記のような設定をした場合では、ルーティングのURIには以下のような表記をしなければいけなくなってしまうのです。

Route::delete('cart={unko}/{deb}’, [CartCobtroller::class, 'destroy’])->name('carts.destroy’);

これでは {unko} {deb} が何のパラメータの値なのかが分からないですよね。

コードを書いた当の本人であればまだ分かるかもしれませんが、それでも1週間もたてば「あれ、{unko}ってCartモデルだっけ、Itemモデルだっけ…」と迷ってしまうことでしょう。

 

ビューからの引数

ビューから複数のパラメータをコントローラに渡す際にも、Laravel側には暗黙のルールがあるようです。

 

左から順番に渡す

例えばフォームタグに以下のようにコードを書くとします。

    <form action="{{ route('carts.destroy’, [$cart, $cart->item_id]) }}" method="post">
(略)

この場合では destroy(Cart $cart, Item $item) の$cart には formの$cart が、$item には $cart->item_id の値が入ります。

分かりやすく言うならば、以下のフォームタグがあったとします。

    <form action="{{ route('carts.destroy’, [$unko, $deb]) }}" method="post">
(略)

この場合も同様に順番に左から値が代入されるため、destroy(Cart $cart, Item $item) の$cart には formの$unkoが、$item には $cart->debの値が入ります。