Posted on

Laravelの豪快な丸呑み:ルートモデル結合

ここ1年程、CakePHPからLaravelへの移行が進んでいってたとこだったんです。

私、先発隊としてLaravelの調査とかテンプレートシステムとか作成する命を受けてまして、色々作っていました。(CakePHP4の時もそうだったんですが。)その中で一つ感動したLaraveの仕組みが「ルートモデル結合」というものです。早い話が「そのid数値をテーブルのレコードidとみなしてEloquentモデルにしたやつ先に取ってきとくよ」という気の利いた仕組みです。

そりゃそうです。何かレコードのidを指定してアクションを組んでいるときに、そのアクションでそのidのレコードと関係ない作業しかしないはずはないわけで、取ってきて欲しいし、なかったら適当に404立てておいて欲しいわけです。ルーティングでは結構CakePHPがよしなにやってくれることに対してぶっきらぼうだったのに、こういうところで気が利くのが面白いところです。

ここでやることは

1:コントローラの引数にEloquentモデルのタイプヒントを付ける

namespace App\Http\Controllers;
use App\Models\User;

class UsersController extends Controller{
    //略
    /**
    * ユーザー編集
    */
    public function edit(User $user){
         //なんか処理、既に$user取得済
    }
    //略
}

…たったこれだけ!暗黙の結合とはいうものの、これだけでほとんどのパターンがカバーできてるのが偉すぎる!

これだけのことで、毎回idから今回の主題となるレコードとその関連レコードをむにゃむにゃ…ということを全部Laravelがやってくれてる状態からスタートするんです。urlの見た目は引き続きidと同じだから、今までのソースを邪魔することもあんまりない。
ルートに->missing()を追加すれば、ないときに404じゃなくてリダイレクト返すというのも簡単。idに対応するレコードが存在しているというだけでは不十分で、何らかの条件を満たしたレコードだけアクセスできるっていう条件が必要なら、それはポリシーの出番やね、というところです。もちろんポリシーにも既に手配したレコードが流れてきてくれてるので、チェックもしやすい。いいことづくめ。

「urlが整数値で入ってきてるから、コントローラも整数値だけを受け取っとるやろな」という常識が、職場でも早く覆ってほしい今日この頃です。