下記の「Laravel 5.2 中級者向けタスクリスト」を、Laravel 7以上での作成する方法をご紹介します。ボリュームが多いので、解説は少なめです。認証機能以外はほぼ同じです。
##作業環境
OS:Windows 10 HOME Edition(ver.2004)
Laravel:7.14.1
Xampp:7.4.6
Composer:1.10.7
Node.js:13.9.0
##①Laravelのインストール
###Composerをインストール
Laravelをインストールするには、Composerというソフトが必要です。
Composerはプログラムの依存関係を解消できるソフトで、簡単に説明するとLaravelを動かすために必要な部品をComposerがまとめて用意してくれる、便利なソフトです。
https://getcomposer.org/
上記のページにアクセスすると、下記のような画面が出てきます。
「Download」を選び、ダウンロードしたファイルをダブルクリックをして、全て「Next」を選んでインストールしておきます。
###Windows PowerShell(管理者)からLaravelをインストールする
PowerShellを管理者権限で実行し、以下のコマンドを打ち、Xamppのhtdocsのフォルダまで移動します。
cd C:\xampp\htdocs
次に以下のコマンドを打ち、Laravelをインストールします。
composer create-project laravel/laravel laravel_todo --prefer-dist
「laravel_todo」はフォルダ名ですので、好きなものを指定してください。
「--prefer-dist」と指定すると解凍したフォルダをダウンロードするので、インストールの時間が短くなります。
Application key set successfully.
上記の表示が出てくれば、Laravelの最新版がインストールが完了です。
また、バージョンを指定した場合は以下のように入力します。
composer create-project laravel/laravel laravel_todo --prefer-dist "6.0.*'
この場合だと、Laravelの「6.0.*」の「*」の部分の数字が一番最新のものがインストールされます。
###Laravelの簡易サーバーを実行する
PowerShellで先程作ったフォルダに移動します。
cd laravel_todo
以下のコマンドを打ち、Larabelの簡易サーバーを起動します。
php artisan serve
XamppのApecheとMySQLを起動して、http://127.0.0.1:8000/ にアクセスし、下記の画面が表示されていればOKです。
※簡易サーバーの実行を止めるには、PowerShellで「Ctrl」+「C」ボタンを押すと止めることができます。
※PowerShellを2つ起動し、1つで簡易サーバーを実行し、残りでコマンドを打っていくのがおすすめです。
##②Laravelの初期設定
Laravelの初期設定を行います。
###Laravelのタイムゾーンと言語設定
Laravelのタイムゾーンと言語設定を行います。
「config」フォルダの中の「app.php」をエディタで開き、該当箇所を下記のように変更します。
70行目 'timezone' => 'Asia/Tokyo',
83行目 'locale' => 'ja',
###データベースの言語設定
データベースの言語設定を行います。
「config」フォルダの中の「database.php」をエディタで開き、該当箇所を下記のように変更します。
55行目 'charset' => 'utf8',
56行目 'collation' => 'utf8_unicode_ci',
###デバックバーのインストール
デバックバーをPowerShellから下記のコマンドを実行してインストールします。
composer require barryvdh/laravel-debugbar
簡易サーバーを起動して、http://127.0.0.1:8000/ にアクセスし、下記の画面が表示されていればOKです。
デバックバーを非表示するには「.env」ファイルを下記のように書き換えます。
4行目 APP_DEBUG=false
##③データベースの準備
###データベースの設定
xamppからphpMyAdminを起動してデータベースとユーザーを設定し、設定した情報を「.env」ファイルに書きこみます。
4行目 DB_CONNECTION=mysql
5行目 DB_HOST=127.0.0.1
6行目 DB_PORT=3306
7行目 DB_DATABASE=laravel_todo
8行目 DB_USERNAME=ユーザー名
9行目 DB_PASSWORD=パスワード
今回は「laravel_todo」というデータベース名にしました。ユーザーを設定しない場合は、Xamppの場合は下記のままでOKです。
4行目 DB_CONNECTION=mysql
5行目 DB_HOST=127.0.0.1
6行目 DB_PORT=3306
7行目 DB_DATABASE=laravel_todo
8行目 DB_USERNAME=root
9行目 DB_PASSWORD=
###データベースマイグレーション
Userテーブルとtasksテーブルを作ります。
Laravelではコマンドを実行することで、テーブルを作れる仕組みになっています。
UserテーブルはLaravelのデフォルトのファイルを使用します。tasksテーブルは、PowerShellで以下のコマンドを実行して作成します。
php artisan make:migration create_tasks_table --create=tasks
「database」フォルダ→「migration」フォルダ→「2020_06_09_111346_create_tasks_table.php」を開きます。
※ファイル名は、作成した日付が先頭に入るので、違うファイル名になりますが問題ありません。
下記のように変更して保存します。
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateTasksTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('tasks', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned()->index();
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('tasks');
}
}
これでtasksテーブルを作る準備ができたので、下記のコマンドを実行し、テーブルを作成します。
php artisan migrate
phpMyAdminを確認すると、下記のようなテーブルが作成されています。
###Eloquentモデル
UserモデルとTaskモデルを作成します。
今回はUserモデルはLaravelが最初から用意してものを使用するので、Taskモデルを作ります。以下のコマンドを実行します。
php artisan make:model Task
「app」フォルダに「Task.php」が作成されるので、以下のように書き換えます。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Task extends Model
{
/**
* 複数代入を行う属性
*
* @var array
*/
protected $fillable = ['name'];
}
###Eloquentリレーション
これでModelが定義できたので、関連付けを行います。
最初にUserモデルに対するtasksリレーションを定義します。「app」フォルダに「User.php」を下記のように追記します。
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
// 他のEloquentプロパティー…
/**
* 特定ユーザーの全タスク取得
*/
public function tasks()
{
return $this->hasMany(Task::class);
}
}
次に、Taskモデルに対するuserリレーションを定義します。「app」フォルダに「Task.php」を下記のように追記します。
<?php
namespace App;
use App\User;
use Illuminate\Database\Eloquent\Model;
class Task extends Model
{
/**
* 複数代入を行う属性
*
* @var array
*/
protected $fillable = ['name'];
/**
* タスク所有ユーザーの取得
*/
public function user()
{
return $this->belongsTo(User::class);
}
}
以上でリレーションができたので、コントローラーを作成します。
##④ルーティング
###認証
Laravel6以降は「php artisan make:auth」というコマンドが使用できないので、公式マニュアルを参照して、以下の手順で認証機能を有効化します。
まずは、次のコマンドを実行し、laravel/uiパッケージをインストールします。
composer require laravel/ui
laravel/uiパッケージをインストールできたら、ui Artisanコマンドを使い、ログイン/ユーザー登録スカフォールドを生成します。今回はbootstrapを使用しますが、vueとreactを使用することもできます。
php artisan ui bootstrap --auth
CSSとJavaScriptをLaravelで生成するために、必要なパッケージをNodeプロジェクトマネージャー(NPM)を使用してインストールします。(Node.jsのインストールが必要です)
npm install
これで準備ができたので、以下のコマンドを実行すると、CSSとJSが生成され、ログイン機能を実装することができます。
npm run dev
実行が終わると、「node_modules」フォルダにたくさんのファルダやファイルが追加されます。例えば、http://127.0.0.1:8000/login にアクセスすると画面が表示されるようになります。
次に認証関連の機能を変更していきます。「app」フォルダ→「Http」フォルダ→「Controllers」フォルダ→「Auth」フォルダの中にある「LoginController.php」を以下のように修正します。
29行目 protected $redirectTo = '/tasks';
同じように、「app/Http/Middleware/RedirectIfAuthenticated.php」ファイルのリダイレクトパスも変更します。
22行目 return redirect('/tasks');
###タスクコントローラー
タスクを取得したり、保存したりする必要がありますので、次のコマンドを実行し、TaskControllerを作成します。
php artisan make:controller TaskController
これでコントローラーが生成できました。続いてこのコントローラーを実行するルートを、次のコマンドを実行して作成します。
php artisan make:controller TaskController
続いて、このコントローラーを実行するルートを「routes/web.php」に以下のように変更します。
<?php
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/tasks', 'TaskController@index');
Route::post('/task', 'TaskController@store');
Route::delete('/task/{task}', 'TaskController@destroy');
作成された「app/Http/Controllers/TaskController.php」を以下のように記述します。
<?php
namespace App\Http\Controllers;
use App\Http\Requests;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class TaskController extends Controller
{
/**
* 新しいコントローラインスタンスの生成
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
}
##⑤レイアウトとビューの構築
###子ビューの定義
TaskControllerのindexメソッドに対応する、「resources/views/tasks/index.blade.php」を作成し、以下の内容を記述します。
<!-- resources/views/tasks/index.blade.php -->
@extends('layouts.app')
@section('content')
<!-- Bootstrapの定形コード… -->
<div class="panel-body">
<!-- バリデーションエラーの表示 -->
@include('common.errors')
<!-- 新タスクフォーム -->
<form action="{{ url('task') }}" method="POST" class="form-horizontal">
{{ csrf_field() }}
<!-- タスク名 -->
<div class="form-group">
<label for="task-name" class="col-sm-3 control-label">Task</label>
<div class="col-sm-6">
<input type="text" name="name" id="task-name" class="form-control">
</div>
</div>
<!-- タスク追加ボタン -->
<div class="form-group">
<div class="col-sm-offset-3 col-sm-6">
<button type="submit" class="btn btn-default">
<i class="fa fa-plus"></i> Add Task
</button>
</div>
</div>
</form>
</div>
<!-- TODO: Current Tasks -->
@endsection
次にTaskControllerのindexメソッドを作成し、このビューを返すようにします。
<?php
namespace App\Http\Controllers;
use App\Http\Requests;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class TaskController extends Controller
{
/**
* 新しいコントローラインスタンスの生成
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* ユーザーの全タスクをリスト表示
*
* @param Request $request
* @return Response
*/
public function index(Request $request)
{
return view('tasks.index');
}
}
##⑥タスク追加
###バリデーション
TaskControllerにstoreメソッドを追加します。
/**
* 新タスク作成
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
$this->validate($request, [
'name' => 'required|max:255',
]);
// タスクの作成処理…
$request->user()->tasks()->create([
'name' => $request->name,
]);
return redirect('/tasks');
}
###$errors変数
「resources/views/common/errors.blade.php」を作成し、以下の内容を記述します。
<!-- resources/views/common/errors.blade.php -->
@if (count($errors) > 0)
<!-- フォームのエラーリスト -->
<div class="alert alert-danger">
<strong>おや?何かがおかしいようです!</strong>
<br><br>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
##⑦既存タスク表示
既存の全タスクをビューに渡すように、TaskController@indexメソッドを編集します。
/**
* ユーザーの全タスクをリスト表示
*
* @param Request $request
* @return Response
*/
public function index(Request $request)
{
$tasks = $request->user()->tasks()->get();
return view('tasks.index', [
'tasks' => $tasks,
]);
}
###依存注入
TaskRepositoryを定義します。「app/Repositories」フォルダを作成し、TaskRepositoryクラスを追加します。
<?php
namespace App\Repositories;
use App\User;
class TaskRepository
{
/**
* 指定ユーザーの全タスク取得
*
* @param User $user
* @return Collection
*/
public function forUser(User $user)
{
return $user->tasks()
->orderBy('created_at', 'asc')
->get();
}
}
TaskControllerに下記のように編集と追記をします。
<?php
namespace App\Http\Controllers;
use App\Task;
use App\Http\Requests;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Repositories\TaskRepository;
class TaskController extends Controller
{
/**
* タスクリポジトリーインスタンス
*
* @var TaskRepository
*/
protected $tasks;
/**
* 新しいコントローラーインスタンスの生成
*
* @param TaskRepository $tasks
* @return void
*/
public function __construct(TaskRepository $tasks)
{
$this->middleware('auth');
$this->tasks = $tasks;
}
/**
* ユーザーの全タスクをリスト表示
*
* @param Request $request
* @return Response
*/
public function index(Request $request)
{
return view('tasks.index', [
'tasks' => $this->tasks->forUser($request->user()),
]);
}
}
###タスク表示
タスクを表示するため、「tasks/index.blade.php」に以下のように追記をします。
@extends('layouts.app')
@section('content')
<!-- タスクフォームの作成… -->
<!-- 現在のタスク -->
@if (count($tasks) > 0)
<div class="panel panel-default">
<div class="panel-heading">
Current Tasks
</div>
<div class="panel-body">
<table class="table table-striped task-table">
<!-- テーブルヘッダ -->
<thead>
<th>Task</th>
<th> </th>
</thead>
<!-- テーブル本体 -->
<tbody>
@foreach ($tasks as $task)
<tr>
<!-- タスク名 -->
<td class="table-text">
<div>{{ $task->name }}</div>
</td>
<td>
<!-- TODO: 削除ボタン -->
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endif
@endsection
##⑧タスク削除
###削除ボタンの追加
「tasks/index.blade.php」に以下を追記
<tr>
<!-- タスク名 -->
<td class="table-text">
<div>{{ $task->name }}</div>
</td>
<!-- 削除ボタン -->
<td>
<form action="{{ url('task/'.$task->id) }}" method="POST">
{{ csrf_field() }}
{{ method_field('DELETE') }}
<button type="submit" id="delete-task-{{ $task->id }}" class="btn btn-danger">
<i class="fa fa-btn fa-trash"></i>削除
</button>
</form>
</td>
</tr>
###ポリシーを作る
PowerShellで以下のコマンドを実行して、TaskPolicyを作成します。
php artisan make:policy TaskPolicy
作成された「app/Policies/TaskPolicy.php」を以下のように編集します。
<?php
namespace App\Policies;
use App\User;
use App\Task;
use Illuminate\Auth\Access\HandlesAuthorization;
class TaskPolicy
{
use HandlesAuthorization;
/**
* 指定されたユーザーが指定されたタスクを削除できるか決定
*
* @param User $user
* @param Task $task
* @return bool
*/
public function destroy(User $user, Task $task)
{
return $user->id === $task->user_id;
}
}
最後に「app/Providers/AuthServiceProvider.php」ファイルの$policiesプロパティに一行加えることで、TaskモデルをTaskPolicyと関連付けします。
<?php
namespace App\Providers;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
class AuthServiceProvider extends ServiceProvider
{
/**
* アプリケーションにマップするポリシー
*
* @var array
*/
protected $policies = [
'App\Task' => 'App\Policies\TaskPolicy',
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
//
}
}
###タスク削除
タスクを削除する機能をTaskControllerに記述します。
/**
* 指定タスクの削除
*
* @param Request $request
* @param Task $task
* @return Response
*/
public function destroy(Request $request, Task $task)
{
$this->authorize('destroy', $task);
$task->delete();
return redirect('/tasks');
}
###見た目を整える
5年前のチュートリアルでBootstrapの記述が古いので、お好みで変更を適宜加えます。
以上で完成です。お疲れさまでした。
##参考ページ
https://readouble.com/laravel/5.2/ja/quickstart-intermediate.html