課題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
