Memo

メモ > 技術 > フレームワーク: Laravel10 > 論理削除に対応したCRUDの新規作成例(分類管理を作成)

論理削除に対応したCRUDの新規作成例(分類管理を作成)
■テーブルの作成
$ sail artisan make:migration create_categories_table
以下のファイルが作成される。 database/migrations/2024_04_18_090608_create_categories_table.php
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { /** * Run the migrations. */ public function up(): void { Schema::create('categories', function (Blueprint $table) { $table->id(); $table->timestamps(); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('categories'); } };
以下のとおり修正する。
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { /** * Run the migrations. */ public function up(): void { Schema::create('categories', function (Blueprint $table) { $table->id(); $table->string('name')->comment('名前'); $table->integer('sort')->comment('並び順'); $table->timestamps(); $table->softDeletes(); $table->comment('分類'); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('categories'); } };
マイグレーションを実行。
$ sail artisan migrate
■モデルの作成
$ sail artisan make:model Category
以下のファイルが作成される。 app/Models/Category.php
<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Category extends Model { use HasFactory; }
以下のとおり修正する。
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; class Category extends Model { use SoftDeletes; protected $fillable = [ 'name', 'sort', ]; }
■リクエストの作成
$ sail artisan make:request CategoryCreateRequest
以下のファイルが作成される。 app/Http/Requests/CategoryCreateRequest.php
<?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class CategoryCreateRequest extends FormRequest { /** * Determine if the user is authorized to make this request. */ public function authorize(): bool { return false; } /** * Get the validation rules that apply to the request. * * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string> */ public function rules(): array { return [ // ]; } }
以下のとおり修正する。
<?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class CategoryCreateRequest extends FormRequest { /** * Determine if the user is authorized to make this request. */ public function authorize(): bool { return true; } /** * Get the validation rules that apply to the request. * * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string> */ public function rules(): array { return [ 'name' => ['required', 'string', 'max:20'], 'sort' => ['required', 'integer'], ]; } public function attributes(): array { return [ 'name' => '名前', 'sort' => '並び順', ]; } }
以下のファイルを作成する。 app/Http/Requests/CategoryUpdateRequest.php
<?php namespace App\Http\Requests; class CategoryUpdateRequest extends CategoryCreateRequest { }
■コントローラーの作成
$ sail artisan make:controller CategoryController
以下のファイルが作成される。 app/Http/Controllers/CategoryController.php
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class CategoryController extends Controller { // }
以下のとおり修正する。
<?php namespace App\Http\Controllers; use App\Http\Requests\CategoryCreateRequest; use App\Http\Requests\CategoryUpdateRequest; use Illuminate\Http\RedirectResponse; use App\Models\Category; use Illuminate\Support\Facades\Redirect; use Illuminate\View\View; class CategoryController extends Controller { public function index(): View { $category = new Category; return view('category.index', [ 'categories' => $category->get(), ]); } public function create(): View { return view('category.form'); } public function store(CategoryCreateRequest $request): RedirectResponse { $category = new Category; $category->fill($request->all())->save(); return Redirect::route('category.index')->with('message', '登録しました。'); } public function edit($id): View { $category = Category::findOrFail($id); return view('category.form', [ 'category' => $category, ]); } public function update(CategoryUpdateRequest $request, $id): RedirectResponse { $category = Category::findOrFail($id); $category->fill($request->all())->save(); return Redirect::route('category.index')->with('message', '編集しました。'); } public function destroy($id): RedirectResponse { $category = Category::findOrFail($id); $category->delete(); return Redirect::route('category.index')->with('message', '削除しました。'); } }
■ビューの作成 以下のファイルを作成する。 resources/views/category/index.blade.php
<x-app-layout> <x-slot name="header"> <h2 class="font-semibold text-xl text-gray-800 leading-tight"> 分類 </h2> </x-slot> <div class="py-12"> <div class="max-w-7xl mx-auto sm:px-6 lg:px-8 space-y-6"> <div class="p-4 sm:p-8 bg-white shadow sm:rounded-lg"> <div class="max-w-xl"> <section> <header> <h2 class="text-lg font-medium text-gray-900"> 分類一覧 </h2> <p class="mt-1 text-sm text-gray-600"> 分類を管理します </p> </header> @if (session('message')) <p class="text-green-600 bg-green-100 my-4 p-4 border-l-4 border-green-400">{{ session('message') }}</p> @elseif (session('error')) <p class="text-red-600 bg-red-100 my-4 p-4 border-l-4 border-red-400">{{ session('error') }}</p> @endif <p class="my-4"><a class="underline text-gray-600 hover:text-gray-900" href="{{ route('category.create') }}">分類登録</a></p> <table class="w-full border shadow"> <thead> <th class="border p-2">名前</th> <th class="border p-2">並び順</th> <th class="border p-2">編集</th> </thead> <tbody> @foreach ($categories as $category) <tr> <td class="border p-2"><div>{{ $category->name }}</div></td> <td class="border p-2"><div>{{ $category->sort }}</div></td> <td class="border p-2"><a class="underline text-gray-600 hover:text-gray-900" href="{{ route('category.edit', ['id' => $category->id]) }}">編集</a></td> </tr> @endforeach </tbody> </table> </section> </div> </div> </div> </div> </x-app-layout>
resources/views/category/form.blade.php
<x-app-layout> <x-slot name="header"> <h2 class="font-semibold text-xl text-gray-800 leading-tight"> 分類 </h2> </x-slot> <div class="py-12"> <div class="max-w-7xl mx-auto sm:px-6 lg:px-8 space-y-6"> <div class="p-4 sm:p-8 bg-white shadow sm:rounded-lg"> <div class="max-w-xl"> <section> <header> <h2 class="text-lg font-medium text-gray-900"> @if (Request::is('*/edit')) {{ '編集' }} @else {{ '登録' }} @endif </h2> <p class="mt-1 text-sm text-gray-600"> 分類を管理します </p> </header> <form method="post" action="{{ Request::is('category/edit/*') ? route('category.update', ['id' => $category->id]) : route('category.store') }}" class="mt-6 space-y-6"> @if (Request::is('category/edit/*')) {{ method_field('patch') }} @endif {{ csrf_field() }} <div> <x-input-label for="name" value="名前" /> <x-text-input id="name" name="name" type="text" class="mt-1 block w-full" value="{{ old('name', isset($category) ? $category->name : '') }}" autofocus autocomplete="name" /> <x-input-error class="mt-2" :messages="$errors->get('name')" /> </div> <div> <x-input-label for="sort" value="並び順" /> <x-text-input id="sort" name="sort" type="text" class="mt-1 block w-full" value="{{ old('sort', isset($category) ? $category->sort : '') }}" autocomplete="sort" /> <x-input-error class="mt-2" :messages="$errors->get('sort')" /> </div> <div class="flex items-center gap-4"> <x-primary-button>@if (!Request::is('*/create')) {{ '編集' }} @else {{ '登録' }} @endif</x-primary-button> </div> </form> </section> </div> </div> @if (Request::is('category/edit/*')) <div class="p-4 sm:p-8 bg-white shadow sm:rounded-lg"> <div class="max-w-xl"> <section> <header> <h2 class="text-lg font-medium text-gray-900"> 削除 </h2> <p class="mt-1 text-sm text-gray-600"> 分類を削除します </p> </header> <form method="post" action="{{ route('category.destroy', ['id' => $category->id]) }}" class="mt-6 space-y-6"> {{ method_field('delete') }} {{ csrf_field() }} <div class="flex items-center gap-4"> <x-danger-button>削除</x-danger-button> </div> </form> </section> </div> </div> @endif </div> </div> </x-app-layout>
■ルーティングの設定 以下のとおり設定する。 routes/web.php
use App\Http\Controllers\CategoryController; Route::middleware('auth')->group(function () { Route::get('/category', [CategoryController::class, 'index'])->name('category.index'); Route::get('/category/create', [CategoryController::class, 'create'])->name('category.create'); Route::post('/category/store', [CategoryController::class, 'store'])->name('category.store'); Route::get('/category/edit/{id}', [CategoryController::class, 'edit'])->name('category.edit'); Route::patch('/category/update/{id}', [CategoryController::class, 'update'])->name('category.update'); Route::delete('/category/destroy/{id}', [CategoryController::class, 'destroy'])->name('category.destroy');
■動作確認 http://laravel.local/category

Advertisement