Laravel | スポット情報管理用の管理画面を追加する方法

Laravelでスポット情報(登録・編集・削除)の管理ができる管理画面を追加する手順を説明します。この記事では、routes/web.php のルーティング設定、コントローラ、Bladeテンプレートを作成し、スポット情報を管理できる仕組みを構築します。

1. スポット情報管理用のルーティング設定

まず、routes/web.php ファイルにスポット情報管理用のルートを追加します。このルートでは、スポット情報の一覧、登録、編集、削除の機能を実装します。

routes/web.php

use App\Http\Controllers\Admin\SpotController as AdminSpotController;

Route::prefix('admin')->group(function () {
    Route::get('/spots', [AdminSpotController::class, 'index'])->name('admin.spots.index');
    Route::get('/spots/create', [AdminSpotController::class, 'create'])->name('admin.spots.create');
    Route::post('/spots', [AdminSpotController::class, 'store'])->name('admin.spots.store');
    Route::get('/spots/{spot}/edit', [AdminSpotController::class, 'edit'])->name('admin.spots.edit');
    Route::put('/spots/{spot}', [AdminSpotController::class, 'update'])->name('admin.spots.update');
    Route::delete('/spots/{spot}', [AdminSpotController::class, 'destroy'])->name('admin.spots.destroy');
});

このルーティングにより、/admin/spots 以下でスポット情報の管理が行えるようになります。


2. 管理画面のコントローラを作成

次に、スポット情報を管理するコントローラを作成します。新規作成、編集、削除、一覧表示の処理を行う SpotController を作成します。

コントローラ作成コマンド

以下のコマンドを実行して、SpotController を作成します。

./vendor/bin/sail artisan make:controller Admin/SpotController

コントローラを作成したら、以下の内容でファイルを編集します。

app/Http/Controllers/Admin/SpotController.php

<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Spot;
use Illuminate\Http\Request;

class SpotController extends Controller
{
    // スポットリストを表示
    public function index()
    {
        $spots = Spot::all();
        return view('admin.spots.index', compact('spots'));
    }

    // スポットの登録画面を表示
    public function create()
    {
        return view('admin.spots.create');
    }

    // 新しいスポットを登録
    public function store(Request $request)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'postal_code' => 'nullable|string|max:255',
            'prefecture' => 'required|string|max:255',
            'address' => 'required|string|max:255',
            'phone_number' => 'nullable|string|max:255',
            'fax' => 'nullable|string|max:255',
            'url' => 'nullable|url',
            'category' => 'required|string|max:255',
            'latitude' => 'nullable|numeric',
            'longitude' => 'nullable|numeric',
            'map_url' => 'nullable|url',
        ]);

        Spot::create($request->all());
        return redirect()->route('admin.spots.index')->with('success', 'スポットを登録しました');
    }

    // スポットの編集画面を表示
    public function edit(Spot $spot)
    {
        return view('admin.spots.edit', compact('spot'));
    }

    // スポットの情報を更新
    public function update(Request $request, Spot $spot)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'postal_code' => 'nullable|string|max:255',
            'prefecture' => 'required|string|max:255',
            'address' => 'required|string|max:255',
            'phone_number' => 'nullable|string|max:255',
            'fax' => 'nullable|string|max:255',
            'url' => 'nullable|url',
            'category' => 'required|string|max:255',
            'latitude' => 'nullable|numeric',
            'longitude' => 'nullable|numeric',
            'map_url' => 'nullable|url',
        ]);

        $spot->update($request->all());
        return redirect()->route('admin.spots.index')->with('success', 'スポット情報を更新しました');
    }

    // スポットを削除
    public function destroy(Spot $spot)
    {
        $spot->delete();
        return redirect()->route('admin.spots.index')->with('success', 'スポットを削除しました');
    }
}

3. 管理画面のレイアウトファイルを作成

次に、共通のレイアウトファイルを作成します。このファイルでは、ナビゲーションバーや共通のHTML構造を定義します。

resources/views/layouts/admin.blade.php

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>管理画面 - @yield('title')</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <nav class="navbar navbar-expand-lg navbar-light bg-light">
        <div class="container-fluid">
            <a class="navbar-brand" href="#">管理画面</a>
            <div class="collapse navbar-collapse">
                <ul class="navbar-nav">
                    <li class="nav-item">
                        <a class="nav-link" href="{{ route('admin.spots.index') }}">スポット管理</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>

    <div class="container mt-4">
        @yield('content')
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

4. スポット情報の一覧表示画面

スポット情報を一覧で表示するビューを作成します。各スポットには編集や削除ができるボタンも追加します。

resources/views/admin/spots/index.blade.php

@extends('layouts.admin')

@section('title', 'スポット管理')

@section('content')
    <h1>スポット管理</h1>
    <a href="{{ route('admin.spots.create') }}" class="btn btn-primary mb-3">新規登録</a>

    @if(session('success'))
        <div class="alert alert-success">
            {{ session('success') }}
        </div>
    @endif

    <table class="table">
        <thead>
            <tr>
                <th>ID</th>
                <th>名前</th>
                <th>住所</th>
                <th>カテゴリ</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
            @foreach($spots as $spot)
                <tr>
                    <td>{{ $spot->id }}</td>
                    <td>{{ $spot->name }}</td>
                    <td>{{ $spot->address }}</td>
                    <td>{{ $spot->category }}</td>
                    <td>
                        <a href="{{ route('admin.spots.edit', $spot) }}" class="btn btn-warning">編集</a>
                        <form action="{{ route('admin.spots.destroy', $spot) }}" method="POST" style="display:inline;">
                            @csrf
                            @method('DELETE')
                            <button type="submit" class="btn btn-danger">削除</button>
                        </form>
                    </td>
                </tr>
            @endforeach
        </tbody>
    </table>
@endsection

5. スポット情報の新規登録画面

スポット情報の新規登録を行うためのビューを作成します。

resources/views/admin/spots/create.blade.php

@extends('layouts.admin')

@section('title', 'スポット登録')

@section('content')
    <h1>新規スポット登録</h1>

    <form action="{{ route('admin.spots.store') }}" method="POST">
        @csrf
        <div class="form-group mb-3">
            <label for="name">名前</label>
            <input type="text" name="name" class="form-control" required>
        </div>
        <div class="form-group mb-3">
            <label for="postal_code">郵便番号</label>
            <input type="text" name="postal_code" class="form-control">
        </div>
        <div class="form-group mb-3">
            <label for="prefecture">都道府県</label>
            <input type="text" name="prefecture" class="form-control" required>
        </div>
        <div class="form-group mb-3">
            <label for="address">住所</label>
            <input type="text" name="address" class="form-control" required>
        </div>
        <div class="form-group mb-3">
            <label for="phone_number">電話番号</label>
            <input type="text" name="phone_number" class="form-control">
        </div>
        <div class="form-group mb-3">
            <label for="fax">FAX番号</label>
            <input type="text" name="fax" class="form-control">
        </div>
        <div class="form-group mb-3">
            <label for="url">URL</label>
            <input type="text" name="url" class="form-control">
        </div>
        <div class="form-group mb-3">
            <label for="category">カテゴリ</label>
            <input type="text" name="category" class="form-control" required>
        </div>
        <div class="form-group mb-3">
            <label for="latitude">緯度</label>
            <input type="text" name="latitude" class="form-control">
        </div>
        <div class="form-group mb-3">
            <label for="longitude">経度</label>
            <input type="text" name="longitude" class="form-control">
        </div>
        <div class="form-group mb-3">
            <label for="map_url">地図URL</label>
            <input type="text" name="map_url" class="form-control">
        </div>
        <button type="submit" class="btn btn-primary">登録</button>
    </form>
@endsection

6. スポット情報の編集画面

スポット情報を編集するためのビューを作成します。編集画面では、既存のデータがフォームに入力済みの状態で表示され、ユーザーが編集を行うことができます。

resources/views/admin/spots/edit.blade.php

@extends('layouts.admin')

@section('title', 'スポット編集')

@section('content')
    <h1>スポット情報編集</h1>

    <form action="{{ route('admin.spots.update', $spot) }}" method="POST">
        @csrf
        @method('PUT')
        <div class="form-group mb-3">
            <label for="name">名前</label>
            <input type="text" name="name" class="form-control" value="{{ old('name', $spot->name) }}" required>
        </div>
        <div class="form-group mb-3">
            <label for="postal_code">郵便番号</label>
            <input type="text" name="postal_code" class="form-control" value="{{ old('postal_code', $spot->postal_code) }}">
        </div>
        <div class="form-group mb-3">
            <label for="prefecture">都道府県</label>
            <input type="text" name="prefecture" class="form-control" value="{{ old('prefecture', $spot->prefecture) }}" required>
        </div>
        <div class="form-group mb-3">
            <label for="address">住所</label>
            <input type="text" name="address" class="form-control" value="{{ old('address', $spot->address) }}" required>
        </div>
        <div class="form-group mb-3">
            <label for="phone_number">電話番号</label>
            <input type="text" name="phone_number" class="form-control" value="{{ old('phone_number', $spot->phone_number) }}">
        </div>
        <div class="form-group mb-3">
            <label for="fax">FAX番号</label>
            <input type="text" name="fax" class="form-control" value="{{ old('fax', $spot->fax) }}">
        </div>
        <div class="form-group mb-3">
            <label for="url">URL</label>
            <input type="text" name="url" class="form-control" value="{{ old('url', $spot->url) }}">
        </div>
        <div class="form-group mb-3">
            <label for="category">カテゴリ</label>
            <input type="text" name="category" class="form-control" value="{{ old('category', $spot->category) }}" required>
        </div>
        <div class="form-group mb-3">
            <label for="latitude">緯度</label>
            <input type="text" name="latitude" class="form-control" value="{{ old('latitude', $spot->latitude) }}">
        </div>
        <div class="form-group mb-3">
            <label for="longitude">経度</label>
            <input type="text" name="longitude" class="form-control" value="{{ old('longitude', $spot->longitude) }}">
        </div>
        <div class="form-group mb-3">
            <label for="map_url">地図URL</label>
            <input type="text" name="map_url" class="form-control" value="{{ old('map_url', $spot->map_url) }}">
        </div>
        <button type="submit" class="btn btn-primary">更新</button>
    </form>
@endsection

動作環境

この記事で使用した動作環境のバージョン情報を紹介します。環境構築にあたって、以下のバージョンのツールを使用しています。

  • Laravel: 11.27.2
  • PHP: 8.3.12
  • MySQL: 8.0.32
  • Composer: 2.8.1
  • League\Csv: 9.16.0

環境設定を行う際は、これらのバージョンに近い環境であることを確認してください。

管理画面のスクリーンショット

以下はスポット管理画面のスクリーンショットです。

スポット一覧画面

この画面では、登録されたスポット情報が一覧表示され、編集・削除ボタンがそれぞれ表示されます。

スポット新規登録画面

新しいスポットを登録する画面です。必要な情報を入力して「登録」ボタンをクリックすることで新しいスポットをデータベースに登録できます。

スポット編集画面

既存のスポット情報を編集する画面です。変更したい項目を修正し、「更新」ボタンを押すことでデータベースが更新されます。


これで、スポット情報の管理用画面を構築するための一連のファイルが完成しました。各ファイルを配置し、コントローラでルーティングを設定することで、スポット情報の登録・編集・削除を行える管理画面を実装できます。

コメント

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