第2回 Laravel11でCRUD(一覧表示してみるの巻)

Laravel
Kiaomoto
Kiaomoto

前回、一覧表示用にテストデータを作成しました。今回は、そのデータを取得して一覧表示してみます。このページでは取得したデータをinertiaを使ってReactに渡して表示するという事を確認します。

前回、データの作成が完了したので、今回はとりあず画面に作成したデータを一覧表示したいと思います。データを取得して、inertiaを使って、Reactに渡すというシンプルながらの基本です。正直、inertiaを使ったことがないので、調べながら実装していきます。

Laravel側に必要なモノを作っていく

まず、Controllerを作るために以下のコマンドを実行します。オプションの–resourceは、リソースコントローラ(簡単に言うとCRUDに必要なメソッドをControllerに一緒に作ってくれる)を作るときに使いますが、付けなくても良いです。

php artisan make:controller ProjectController --resource

実行すると以下のファイルが作成されます。リソースコレクションのクラスをこの後、作成するのですが、作成後に以下の様に修正を行って下さい。ViewにProject/indexを使い、そのViewに全件取得したprojectのデータをprojectsという名前で、titleという名前で”Project”というテキストを渡してます。

app/Http/Controllers/ProjectController.php

<?php

namespace App\Http\Controllers;

use App\Http\Resources\ProjectCollection; // あとで追加してください
use App\Models\Project;
use Illuminate\Http\Request;

class ProjectController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
    // これを追加
        return Inertia::render('Project/index', [
            'projects' => new ProjectCollection(Project::all()),
            'title' => 'Project',
        ]);
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        //
    }

   // 長いので以下省略

}

次にリソースコレクションのクライスを作成します。今回は修正せずにそのまま使います。これが何をするクラスなのかというとモデルのデータを返す時にJSONに変換したりする処理を担う部分になります。詳しくは、もう少し作り込んでいく段階で修正していくと思うので、その際に説明します。

php artisan make:resource Project --collection

app/Http/Resources/ProjectCollection.php

<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\ResourceCollection;

class ProjectCollection extends ResourceCollection
{
    /**
     * Transform the resource collection into an array.
     *
     * @return array<int|string, mixed>
     */
    public function toArray(Request $request): array
    {
        return parent::toArray($request);
    }
}

次にコントローラーにアクセス出来るようにルートを追加します。/peojectにアクセスするとProjectControllerindexが呼び出される様にしています。

routes/web.php

// 長いのでここまで省略

Route::middleware('auth')->group(function () {
    Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit');
    Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update');
    Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');

    //これを追加
    Route::get('/project',[ProjectController::class, 'index']);
});

// 長いので以下、省略

最後にViewを作成していきます。まずは、取得したprojectデータの型を定義します。

resources/js/types/index.d.ts

export interface User {
  id: number
  name: string
  email: string
  email_verified_at?: string
}

export type PageProps<
  T extends Record<string, unknown> = Record<string, unknown>
> = T & {
  auth: {
    user: User
  }
}

// これを追加
export type Project = {
  id: number
  name: string
  description: string
}

最後に一覧表示用のファイルを作成します。cssについてはtailwind CSSをそのまま一旦使っています。データの受け渡しについては、もともと、index.d.tsで定義されていた、PagePropsをそのまま使っています。authとかの部分はLaravel側のmiddlewareで毎度、情報を突っ込んで返してるのは確認したんですが、一旦、そのままにして今回は使おうと思います。

resources/js/Pages/Project/index.tsx

import { Head } from '@inertiajs/react'
import { PageProps, Project } from '@/types'

export default function Index({
  projects,
  title
}: PageProps<{ projects: { data: Project[] }; title: string }>) {
  return (
    <>
      <Head title={title} />
      <table className="table-auto">
        <thead className="sticky top-0 z-10 ">
          <tr className="bg-gray-200">
            <th className="px-4 py-2 border ">Id</th>
            <th className="px-4 py-2 border ">Name</th>
            <th className="px-4 py-2 border ">Description</th>
          </tr>
        </thead>
        <tbody>
          {projects.data.map((project: Project) => (
            <tr key={project.id}>
              <td className="px-4 py-2 border ">{project.id}</td>
              <td className="px-4 py-2 border ">{project.name}</td>
              <td className="px-4 py-2 border ">{project.description}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </>
  )
}

ここまで準備ができたら、npm run devを実行して、ブラウザでlocalhost/projectにアクセスしてみてください。下記の様な画面が表示されます。

今日は、ここまで。

タイトルとURLをコピーしました