keigo-uの備忘録

沖縄で情報系の大学に通う大学生の技術ブログです。

明示的な結合

概要

Laravelのルートパラメータでは暗黙の結合により、パラメータ名と同名のモデルからidの対応する値を取得してくれますが、その結合を明示的に行うことで、id以外の値で取得したり、絞り込みなどを行う。

おさらい:暗黙の結合とは

// web.php
Route::get('posts/{post}', [PostController::class, 'show']);
// PostController.php
public function index(Post $post) {
    // 省略
}

上記のようなルートがあるときに、ルートパラメータである{post}の値をidとして、Postモデルのインスタンスを生成してコントローラーで受け取ることができる。

設定方法

明示的な結合を行うための設定方法はいくつかありますが、ここでは2つ紹介します。

RouteServiceProviderに記述する方法

app/Providers/RouteServiceProvider.phpのbootメソッドでパラメータ名に対応するモデルを指定します。

// 追記
use App\Models\Post;
use Illuminate\Support\Facades\Route;

/**
 * ルートモデルの結合、パターンフィルターなどを定義
 *
 * @return void
 */
public function boot()
{
    Route::bind('post', function ($value) {
        return Post::where('name', $value)->firstOrFail();
    });

    // 省略
}

Modelファイルに記述する方法

モデルファイルのresolveRouteBindingメソッドをオーバーライドすることでも設定することができます。

// Post.php
/**
 * 値と結合するモデルの取得
 * 
 */
public function resolveRouteBinding($value, $field = null)
{
    return $this->where('name', $value)->findOrFail($value);
}