課題2020-11

ログイン機能を有した簡単な会員管理システムを作ります。
ログイン機能はLaravelが提供する標準ログイン機能を使います。
DBテーブルへのアクセスはすべてモデルを介して行うこととする。
一覧ページにはページング機能を実装する。1ページあたり10件表示することとする。

テーブル定義

会員テーブル (members)

  • ID
  • 名前
  • グループID
  • 作成日時(created_at)
  • 更新日時(updated_at)

グループテーブル (groups)

  • ID
  • 名前
  • 作成日時(created_at)
  • 更新日時(updated_at)

画面設計

解答例

マイグレーション

<?php

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

class CreateMembersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('members', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name', 100);
            $table->integer('group_id');
            $table->timestamps();
        });
    }

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

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

class CreateGroupTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('groups', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name', 100);
            $table->timestamps();
        });
    }

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

シーディング

<?php

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class GroupsSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $date = date('Y-m-d H:i:s');

        for($count=0; $count<10; $count++) {
            DB::insert('INSERT INTO groups (name, created_at, updated_at) values(?, ?, ?);', [
                'グループ' . $count,
                $date,
                $date
            ]);
        }
    }
}
<?php

use Illuminate\Database\Seeder;
use App\Member;

class MembersSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        for($count = 0; $count < 100; $count++) {
            $member = new Member;
            $member->name = 'メンバー' . $count;
            $member->group_id = 1;
            $member->save();
        }
    }
}

ルーティング

// 一覧画面
Route::get('/members', 'MembersController@index');
// 新規登録画面
Route::get('/members/create', 'MembersController@create');
// 新規登録処理
Route::post('/members', 'MembersController@store');
// 編集画面
Route::get('/members/{id}/edit', 'MembersController@edit');
// 更新処理
Route::post('/members/{id}', 'MembersController@update');
// 削除処理
Route::delete('/members/{id}', 'MembersController@destroy');

コントローラ

<?php

namespace App\Http\Controllers;

use App\Member;
use App\Group;
use Illuminate\Http\Request;
use App\Http\Requests\MemberRequest;

class MembersController extends Controller
{
    /**
     * 一覧画面
     */
    public function index(Request $request) {
        $name = $request->name;
        $group_id = $request->group_id;

        $groups = Group::orderBy('id', 'asc')->get();

        $query = Member::select([
            'members.id',
            'members.name',
            'groups.name as group_name'
        ]);
        $query->join('groups', 'members.group_id', '=', 'groups.id');
        if(!is_null($name)) {
            $query->where('members.name', 'like', '%' . $name . '%');
        }
        if(!is_null($group_id)) {
            $query->where('members.group_id', '=', $group_id);
        }
        $query->orderBy('members.id', 'desc');
        $members = $query->paginate(20);

        return view('members.index', [
            'groups' => $groups,
            'members' => $members
        ]);
    }

    /**
     * 新規登録画面
     */
    public function create() {
        $groups = Group::orderBy('id', 'asc')->get();

        return view('members.create', [
            'groups' => $groups
        ]);
    }

    /**
     * 新規登録処理
     */
    public function store(MemberRequest $request) {
        $member = new Member;
        $member->name = $request->name;
        $member->group_id = $request->group_id;
        $member->save();

        return redirect('/members');
    }

    /**
     * 編集画面
     */
    public function edit($id) {
        $member = Member::find($id);
        $groups = Group::orderBy('id', 'asc')->get();

        return view('members.edit', [
            'member' => $member,
            'groups' => $groups
        ]);
    }

    /**
     * 更新処理
     */
    public function update($id, MemberRequest $request) {
        $member = Member::find($id);
        $member->name = $request->name;
        $member->group_id = $request->group_id;
        $member->save();

        return redirect('/members');
    }

    /**
     * 削除処理
     */
    public function destroy($id) {
        $member = Member::find($id);
        $member->delete();

        return redirect('/members');
    }
}

リクエスト

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class MemberRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name' => 'required|string|max:100',
            'group_id' => 'required|integer'
        ];
    }
}

ビュー

@extends('layouts.app')

@section('content')
<div class="container">
    <a class="btn btn-primary mb-3" href="/members/create">新規登録</a>
    <form>
        <p>
            名前<br>
            <input class="form-control" type="text" name="name">
        </p>
        <p>
            グループ<br>
            <select name="group_id" class="form-control">
                <option></option>
                @foreach($groups as $group)
                    <option value="{{ $group->id }}">{{ $group->name }}</option>
                @endforeach
            </select>
        </p>
        <p>
            <input class="btn btn-primary" type="submit" value="検索">
        </p>
    </form>
    {{ $members->links() }}
    <table class="table">
        <thead>
            <tr>
                <th>ID</th>
                <th>名前</th>
                <th>グループ名</th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            @foreach($members as $member)
            <tr>
                <td>{{ $member->id }}</td>
                <td>{{ $member->name }}</td>
                <td>{{ $member->group_name }}</td>
                <td>
                    <div class="d-flex">
                        <a class="btn btn-secondary mr-1" href="/members/{{ $member->id }}/edit">編集</a>
                        <form method="POST" action="/members/{{ $member->id }}">
                            @method('delete')
                            @csrf
                            <input class="btn btn-danger" type="submit" value="削除">
                        </form>
                    </div>
                </td>
            </tr>
            @endforeach
        </tbody>
    </table>
</div>
@endsection
@extends('layouts.app')

@section('content')
<div class="container">
    <ul>
    @if($errors->any())
        @foreach($errors->all() as $error)
            <li>{{ $error }}</li>
        @endforeach
    @endif
    </ul>
    <form method="POST" action="/members">
        @csrf
        <p>
            名前<br>
            <input class="form-control" type="text" name="name" value="{{ old('name') }}">
        </p>
        <p>
            グループ<br>
            <select name="group_id" class="form-control">
                <option value></option>
                @foreach($groups as $group)
                <option value="{{ $group->id }}" {{ $group->id == old('group_id') ? 'selected' : '' }}>{{ $group->name }}</option>
                @endforeach
            </select>
        </p>
        <p>
            <a class="btn btn-secondary" href="/members">戻る</a>
            <input class="btn btn-primary" type="submit" value="登録">
        </p>
    </form>
</div>
@endsection
@extends('layouts.app')

@section('content')
<div class="container">
    <ul>
    @if($errors->any())
        @foreach($errors->all() as $error)
            <li>{{ $error }}</li>
        @endforeach
    @endif
    </ul>
    <form method="POST" action="/members/{{ $member->id }}">
        @csrf
        <p>
            名前<br>
            <input class="form-control" type="text" name="name" value="{{ old('name', $member->name) }}">
        </p>
        <p>
            グループ<br>
            <select name="group_id" class="form-control">
                <option value></option>
                @foreach($groups as $group)
                <option value="{{ $group->id }}" {{ $group->id == old('group_id', $member->group_id) ? 'selected' : '' }}>{{ $group->name }}</option>
                @endforeach
            </select>
        </p>
        <p>
            <a class="btn btn-secondary" href="/members">戻る</a>
            <input class="btn btn-primary" type="submit" value="保存">
        </p>
    </form>
</div>
@endsection

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

SQL

前の記事

集約関数とGROUP BY
Laravel

次の記事

モデル(Model)を使う