メモ > 技術 > フレームワーク: Laravel6 > シンプルなCRUDの新規作成例(カテゴリ管理を作成)
シンプルなCRUDの新規作成例(カテゴリ管理を作成)
マイグレーションを作成
$ php artisan make:migration create_categories_table
作成されたマイグレーションを以下のように修正
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->bigIncrements('id');
$table->string('name')->nullable()->comment('名前');
$table->integer('sort')->comment('並び順');
$table->timestamps();
$table->softDeletes();
});
DB::statement('ALTER TABLE categories COMMENT \'カテゴリ\'');
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('categories');
}
マイグレーションを実行
$ php artisan migrate
プログラムを作成
app/Models/Category.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Category extends Model
{
use SoftDeletes;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'sort',
];
}
app/Contracts/Repositories/CategoryRepository.php
<?php
namespace App\Contracts\Repositories;
interface CategoryRepository
{
/**
* 取得
*
* @param int $id
* @return mixed
*/
public function find($id);
/**
* 検索
*
* @param array $conditions
* @param array $orders
* @param int|null $limit
* @return mixed
*/
public function search(array $conditions, array $orders, $limit);
/**
* 件数
*
* @return int
*/
public function count();
/**
* 保存
*
* @param array $data
* @param int|null $id
* @return mixed
*/
public function save(array $data, $id);
/**
* 削除
*
* @param int $id
* @return mixed
*/
public function delete($id);
}
app/Repositories/CategoryRepository.php
<?php
namespace App\Repositories;
use App\Contracts\Repositories\CategoryRepository as CategoryRepositoryContract;
use App\Models\Category;
class CategoryRepository implements CategoryRepositoryContract
{
/** @var Category */
protected $category;
/**
* コンストラクタ
*
* @param Category $category
* @return void
*/
public function __construct(Category $category)
{
$this->category = $category;
}
/**
* 取得
*
* @param int $id
* @return mixed
*/
public function find($id)
{
return $this->category->find($id);
}
/**
* 検索
*
* @param array $conditions
* @param array $orders
* @param int|null $limit
* @return mixed
*/
public function search(array $conditions = array(), array $orders = array(), $limit = null)
{
$query = $this->category->query();
$query = $this->setConditions($query, $conditions);
foreach ($orders as $order) {
$query->orderBy($order[0], $order[1]);
}
if ($limit == null) {
return $query->get();
} else {
return $query->paginate($limit);
}
}
/**
* 件数
*
* @param array $conditions
* @return int
*/
public function count(array $conditions = array())
{
$query = $this->category->query();
$query = $this->setConditions($query, $conditions);
return $query->count();
}
/**
* 保存
*
* @param array $data
* @param int|null $id
* @return Category
*/
public function save(array $data, $id = null)
{
return $this->category->updateOrCreate(['id' => $id], $data);
}
/**
* 削除
*
* @param int $id
* @return mixed
*/
public function delete($id)
{
return $this->category->findOrFail($id)->delete();
}
/**
* 検索条件を設定
*
* @param int $query
* @param array $conditions
* @return \Illuminate\Database\Query\Builder
*/
private function setConditions($query, array $conditions = array())
{
if (isset($conditions['id'])) {
$query->where('id', $conditions['id']);
}
if (isset($conditions['name'])) {
$query->where('name', $conditions['name']);
}
if (isset($conditions['name_like'])) {
$query->where('name', 'like', $conditions['name_like']);
}
return $query;
}
}
app/Services/CategoryService.php
<?php
namespace App\Services;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Contracts\Repositories\CategoryRepository;
use App\Http\Requests\StoreCategoryRequest;
use App\Http\Requests\UpdateCategoryRequest;
class CategoryService
{
/** @var CategoryRepository */
protected $categoryRepository;
/**
* コンストラクタ
*
* @param CategoryRepository $categoryRepository
* @return void
*/
public function __construct(CategoryRepository $categoryRepository)
{
$this->categoryRepository = $categoryRepository;
}
/**
* 1件取得
*
* @param int $id
* @return mixed
*/
public function getCategory($id)
{
return $this->categoryRepository->find($id);
}
/**
* 検索して取得
*
* @param array $conditions
* @param array $orders
* @param int $limit
* @return mixed
*/
public function getCategories(array $conditions = array(), array $orders = array(), $limit = null)
{
return $this->categoryRepository->search($conditions, $orders, $limit);
}
/**
* 件数を取得
*
* @param array $conditions
* @return int
*/
public function countCategories(array $conditions = array())
{
return $this->categoryRepository->count($conditions);
}
/**
* 登録
*
* @param StoreCategoryRequest $request
* @return \App\Models\Category
*/
public function storeCategory(StoreCategoryRequest $request)
{
$input = $request->only([
'name',
'sort',
]);
// 保存
try {
return DB::transaction(function () use ($input) {
$result = $this->categoryRepository->save($input);
return $result;
});
} catch (\Exception $e) {
Log::error('CategoryService:storeCategory', ['message' => $e->getMessage(), 'input' => $input]);
return null;
}
}
/**
* 編集
*
* @param UpdateCategoryRequest $request
* @param int $id
* @return \App\Models\Category
*/
public function updateCategory(UpdateCategoryRequest $request, $id)
{
$input = $request->only([
'name',
'sort',
]);
// 保存
try {
return DB::transaction(function () use ($input, $id) {
$result = $this->categoryRepository->save($input, $id);
return $result;
});
} catch (\Exception $e) {
Log::error('CategoryService:updateCategory', ['message' => $e->getMessage(), 'input' => $input, 'id' => $id]);
return null;
}
}
/**
* 削除
*
* @param int $id
* @return \App\Models\Category
*/
public function deleteCategory($id)
{
try {
return DB::transaction(function () use ($id) {
return $this->categoryRepository->delete($id);
});
} catch (\Exception $e) {
Log::error('CategoryService:deleteCategory', ['message' => $e->getMessage(), 'id' => $id]);
return null;
}
}
}
app/Providers/AppServiceProvider.php
$this->app->bind(
\App\Contracts\Repositories\CategoryRepository::class,
\App\Repositories\CategoryRepository::class
);
app/Http/Requests/StoreCategoryRequest.php
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StoreCategoryRequest 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:255'],
'sort' => ['required', 'integer'],
];
}
/**
* バリデーションエラーのカスタム属性の取得
*
* @return array
*/
public function attributes()
{
return [
'name' => '名前',
'sort' => '並び順',
];
}
}
main/app/Http/Requests/UpdateCategoryRequest.php
<?php
namespace App\Http\Requests;
class UpdateCategoryRequest extends StoreCategoryRequest
{
}
app/Http/Controllers/Admin/CategoryController.php
<?php
namespace App\Http\Controllers\Admin;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Requests;
use App\Http\Requests\StoreCategoryRequest;
use App\Http\Requests\UpdateCategoryRequest;
use App\Models\Category;
use App\Services\CategoryService;
class CategoryController extends Controller
{
/**
* Create a new controller instance.
*
* @param CategoryService $categoryService
* @return void
*/
public function __construct(CategoryService $categoryService)
{
$this->middleware('auth');
$this->categoryService = $categoryService;
}
/**
* Display a list of all categories.
*
* @param Request $request
* @return Response
*/
public function index(Request $request)
{
return view('admin.category.index', [
'categories' => $this->categoryService->getCategories([], [['id', 'desc']]),
]);
}
/**
* Display a form of new category.
*
* @param Request $request
* @return Response
*/
public function create(Request $request)
{
return view('admin.category.form');
}
/**
* Create a new category.
*
* @param Request $request
* @return Response
*/
public function store(StoreCategoryRequest $request)
{
if ($this->categoryService->storeCategory($request)) {
return redirect()->route('admin.category.index')->with('message', 'カテゴリを登録しました。');
} else {
return redirect()->route('admin.category.index')->with('error', 'カテゴリを登録できませんでした。');
}
}
/**
* Display a form of edit category.
*
* @param Request $request
* @return Response
*/
public function edit(Request $request, $id)
{
return view('admin.category.form', [
'category' => $this->categoryService->getCategory($id),
]);
}
/**
* Update a category.
*
* @param Request $request
* @return Response
*/
public function update(UpdateCategoryRequest $request, $id)
{
if ($this->categoryService->updateCategory($request, $id)) {
return redirect()->route('admin.category.index')->with('message', 'カテゴリを編集しました。');
} else {
return redirect()->route('admin.category.index')->with('error', 'カテゴリを編集できませんでした。');
}
}
/**
* Destroy the given category.
*
* @param Request $request
* @param string $id
* @return Response
*/
public function destroy(Request $request, $id)
{
if ($this->categoryService->deleteCategory($id)) {
return redirect()->route('admin.category.index')->with('message', 'カテゴリを削除しました。');
} else {
return redirect()->route('admin.category.index')->with('error', 'カテゴリを削除できませんでした。');
}
}
}
resources/views/admin/home.blade.php
<li><a href="{{ route('admin.category.index') }}">カテゴリ管理</a></li>
resources/views/admin/category/index.blade.php
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">カテゴリ一覧</div>
<div class="card-body">
@if (session('message'))
<div class="box">
<div class="alert alert-success">
{{ session('message') }}
</div>
</div>
@elseif (session('error'))
<div class="box">
<div class="alert alert-danger">
{{ session('error') }}
</div>
</div>
@endif
<p><a href="{{ route('admin.category.create') }}" class="btn btn-primary">カテゴリ登録</a></p>
<table class="table table-striped">
<thead>
<th>名前</th>
<th>並び順</th>
<th>編集</th>
<th>削除</th>
</thead>
<tbody>
@foreach ($categories as $category)
<tr>
<td class="table-text"><div>{{ $category->name }}</div></td>
<td class="table-text"><div>{{ $category->sort }}</div></td>
<td class="table-text"><a href="{{ route('admin.category.edit', ['id' => $category->id]) }}" class="btn btn-primary">Edit</a></td>
<td>
<form action="{{ route('admin.category.delete', ['id' => $category->id]) }}" method="POST">
{{ csrf_field() }}
{{ method_field('DELETE') }}
<button type="submit" class="btn btn-danger">
Delete
</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
@endsection
resources/views/admin/category/form.blade.php
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">カテゴリ @if (!Request::is('*/create')) {{ '編集' }} @else {{ '登録' }} @endif</div>
<div class="card-body">
@if (count($errors) > 0)
<div class="alert alert-danger">
@foreach ($errors->all() as $error)
{{ $error }}<br>
@endforeach
</div>
@endif
<form action="{{ Request::is('*/create') ? route('admin.category.create') : route('admin.category.edit', ['id' => $category->id]) }}" method="POST" class="form-horizontal">
@if (!Request::is('*/create'))
{{ method_field('put') }}
@endif
{{ csrf_field() }}
<div class="form-group">
<label for="name" class="col-sm-3 control-label">名前</label>
<div class="col-sm-6">
<input type="text" name="name" id="name" class="form-control" value="{{ old('name', isset($category) ? $category->name : '') }}">
</div>
</div>
<div class="form-group">
<label for="sort" class="col-sm-3 control-label">並び順</label>
<div class="col-sm-6">
<input type="text" name="sort" id="sort" class="form-control" value="{{ old('sort', isset($category) ? $category->sort : '') }}">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-6">
<button type="submit" class="btn btn-primary">
<i class="fa fa-btn fa-plus"></i>@if (!Request::is('*/create')) {{ '編集' }} @else {{ '登録' }} @endif
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
@endsection
routes/web.php
// カテゴリ管理
Route::get('/category', 'CategoryController@index')->name('.category.index');
Route::get('/category/create', 'CategoryController@create')->name('.category.create');
Route::post('/category/create', 'CategoryController@store')->name('.category.store');
Route::get('/category/edit/{id}', 'CategoryController@edit')->name('.category.edit');
Route::put('/category/edit/{id}', 'CategoryController@update')->name('.category.update');
Route::delete('/category/delete/{id}', 'CategoryController@destroy')->name('.category.delete');