🗂️

【Laravel】UUIDカラムをURLに割り当てるとルートに割当されなかった場合の対策

2022/03/22に公開

概要

主キーをUUIDにする必要があったので以下の記事を参考に導入した。

ルートモデルバインディングでUUIDを割り当てると404エラーでルートに到達できない事象があったので解決方法をまとめる

web.php
<?php
Route::prefix('post')->group(function () {
    Route::get('/edit/{uuid?}', [PostController::class, 'edit'])->name('admin.posts.edit');
});

https://qiita.com/ucan-lab/items/a8374ba421fe7828dcb9

環境

  • PHP 7.4.25
  • Laravel Framework 6.20.44
  • laravel-eloquent-uuid v6.*

導入手順

https://github.com/goldspecdigital/laravel-eloquent-uuid

composer require goldspecdigital/laravel-eloquent-uuid:^6.0

マイグレーション作成

CreatePostsTable
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->uuid('uuid')->primary();
            $table->string('name', 255);
            $table->text('note')->nullable();
            $table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
            $table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

モデル作成

Post.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    /**
     * モデルに関連付けるテーブル
     *
     * @var string
     */
    protected $table = 'posts';

    /**
     * テーブルに関連付ける主キー
     *
     * @var string
     */
    protected $primaryKey = 'uuid';

    /**
     * モデルのIDを自動増分するか
     *
     * @var bool
     */
    public $incrementing = false;

    /**
     * 複数代入可能な属性
     *
     * @var array
     */
    protected $fillable = ['uuid', 'name', 'note'];
}

Bladeテンプレートを作成

  • リンクをクリックすることで以下のルートに割り当てられる想定だったが404が返ってきた
web.php
<?php
Route::prefix('post')->group(function () {
    Route::get('/edit/{uuid?}', [PostController::class, 'edit'])->name('admin.posts.edit');
});
index.blade.php
@foreach ($posts as $post)
    <tr>
        <td>
            <a href="{{route('admin.posts.edit',['uuid'=>$post->uuid])}}">
                {{ $post->uuid }}
            </a>
        </td>
    </tr>
@endforeach

解決方法

  • キーのカスタマイズを行う必要があるので以下のようにすることで 期待通りルーティングされる

https://github.com/michaeldyrynda/laravel-model-uuid/issues/104

https://laravel.com/docs/8.x/routing#customizing-the-key

web.php
<?php
Route::prefix('post')->group(function () {
    Route::get('/posts/{uuid?}', [PostController::class, 'edit'])->name('admin.posts.edit');
});
GitHubで編集を提案

Discussion