Laravel入門しようと思い立ったので、とりあえずXAMPPでやってみました。
Laravel5.2のチュートリアルをなんとなく参考に、タスク管理を作って基本的なCRUDをやってみます。
今回はログインとか認証は一切ありません。
使ってるLaravelは5.3です。
Composerインストール
XAMPPのシェルでComposerをインストールします。
php -r "readfile('https://getcomposer.org/installer');" | php
Laravelインストール
exampleプロジェクトを作成します。
php composer.phar create-project laravel/laravel example --prefer-dist
とりあえずLaravel
http://localhost/example/public/
Laravelのバージョンは5.3です。
データベース
XAMPP使ってるのでMySQL(Maria DB)を使います。
事前にMySQLにユーザーとデータベースを作っておきます。
データベースの接続情報を.envに設定します。
DB_DATABASE=example
DB_USERNAME=example
DB_PASSWORD=example
tasksテーブルを作成するためのマイグレーションを作ります。
XAMPPシェルでartisanを使います。
php artisan make:migration create_tasks_table --create=tasks
database/migrationsにマイグレーションファイルが作成されます。
マイグレーションファイルを修正してテーブルに作成するカラムを指定します。
public function up()
{
Schema::create('tasks', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->nullable();
$table->boolean('done')->default(false);
$table->timestamps();
$table->softDeletes();
});
}
nameカラムとdoneカラムを追加しました。
あと、論理削除に対応するため$table->softDeletes()
を追加しています。
マイグレーションを実行してテーブルを作成します。
php artisan migrate
Modelの作成
artisanでTaskモデルを作ります。
php artisan make:model Task
app/Task.phpができるので、編集します。
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Task extends Model
{
use SoftDeletes;
protected $fillable = [
'name',
'done',
];
}
use SoftDeletes
で、このモデルをdestoryしたときに論理削除されるようになります。
$fillable
はこのモデルで使うリクエストパラメータを指定しておきます。
Controllerの作成
artisanでTaskコントローラを作成します。
php artisan make:controller TasksController
app/Http/ContollersにTasksControllerができます。
ルーティング
LaravelではResourcefulなルートに対応してるので、それでいきます。
routes/web.phpを編集します。
Route::resource('tasks', 'TasksController');
この1行で次の7つのアクションが定義されます。
参考に公式ドキュメントの表を転記しておきます。
Verb | URI | Action | Route Name |
---|---|---|---|
GET | /tasks | index | tasks.index |
GET | /tasks/create | create | tasks.create |
POST | /tasks | store | tasks.store |
GET | /tasks/{task} | show | tasks.show |
GET | /tasks/{task}/edit | edit | tasks.edit |
PUT/PATCH | /tasks/{task} | update | tasks.update |
DELETE | /tasks/{task} | destroy | tasks.destroy |
https://laravel.com/docs/5.3/controllers#resource-controllers
Railsと比較するとcreate→store, new→createとなっているのでRailsに慣れている人はご注意。
Viewレイアウトの作成
Viewで共通して使うレイアウトを作ります。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>@yield('title')</title>
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
<div class="container">
<nav class="navbar navbar-default">
<a class="navbar-brand" href="{{ url('/tasks') }}">
タスク一覧
</a>
<a class="navbar-brand" href="{{ url('/tasks/create') }}">
新規作成
</a>
</nav>
</div>
@yield('content')
<script src="{{ asset('js/app.js') }}"></script>
</body>
</html>
Formヘルパーを使う
Laravel5からFormヘルパーは別プロジェクトになったようなので、インストールします。
php ../composer.phar require laravelcollective/html
config/app.phpを編集してprovidersとaliasesに設定を追加します。
'providers' => [
Collective\Html\HtmlServiceProvider::class,
'aliases' => [
'Form' => Collective\Html\FormFacade::class,
'Html' => Collective\Html\HtmlFacade::class,
新規登録画面の作成
TasksControllerにcreateアクションとstoreアクションを作ります。
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Task;
use App\Http\Requests;
class TasksController extends Controller
{
public function create()
{
return view('tasks/create')->with('task', new Task());
}
public function store(Request $request)
{
$task = new Task();
$task->fill($request->all());
$task->save();
return redirect()->route('tasks.index');
}
}
storeではDBに保存して一覧にリダイレクトしているだけです。
Validationなどはしていません。
Modelの$fillable
にフィールド名を定義しておくと、$task->fill
でリクエストパラメータから値を取得してくれます。(Railsのstrong parametersみたいな感じ)
Viewの作成
新規作成画面のViewを作ります。
@extends('layouts.app')
@section('title', '新規作成')
@section('content')
<div class="panel panel-default">
<div class="panel-heading">
新規作成
</div>
<div class="panel-body">
{!! Form::model($task, ['route' => 'tasks.store', 'method' => 'post', 'class' => 'form-horizontal']) !!}
<div class="form-group">
{!! Form::label('name', 'タスク名', ['class' => 'col-sm-3 control-label']) !!}
<div class="col-sm-6">
{!! Form::text('name', $task->name, ['id' => 'task-name', 'class' => 'form-control']) !!}
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-6">
{!! Form::submit('タスク追加', ['class' => 'btn btn-default']) !!}
</div>
</div>
{!! Form::close() !!}
</div>
<div class="panel-footer">
{{ link_to_route('tasks.index', '戻る') }}
</div>
</div>
@endsection
http://localhost/example/public/tasks/create
新規作成画面ができました。
一覧画面を作成
TasksControllerにindexアクションを作ります。
public function index()
{
$tasks = Task::orderBy('updated_at', 'desc')->get();
return view('tasks/index')->with('tasks', $tasks);
}
Viewを作ります。
@extends('layouts.app')
@section('title', 'タスク一覧')
@section('content')
<div class="panel panel-default">
<div class="panel-heading">
タスク一覧
</div>
<div class="panel-body">
<table class="table table-striped task-table">
<thead>
<th>タスク名</th>
<th>完了</th>
<th>編集</th>
<th>削除</th>
</thead>
<tbody>
@foreach ($tasks as $task)
<tr>
<td class="table-text">
{{ link_to_route('tasks.show', $task->name, $task->id) }}
</td>
<td class="table-text">
{{ $task->done ? '完了' : '未' }}
</td>
<td class="table-text">
{{ link_to_route('tasks.edit', '編集', $task->id, ['class' => 'btn btn-sm btn-default']) }}
</td>
<td class="table-text">
{{ Form::open(['route' => ['tasks.destroy', $task->id], 'method' => 'delete']) }}
{{ Form::hidden('id', $task->id) }}
{{ Form::submit('削除', ['class' => 'btn btn-sm btn-default']) }}
{{ Form::close() }}
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endsection
http://localhost/example/public/tasks
新規登録すると一覧に表示されます。
詳細画面の作成
コントローラにshowアクションを作ります。
public function show($id)
{
$task = Task::find($id);
return view('tasks/show')->with('task', $task);
}
Viewを作ります。
@extends('layouts.app')
@section('title', $task->name)
@section('content')
<div class="panel panel-default">
<div class="panel-heading">
{{ $task->name }}
</div>
<div class="panel-body">
<div>
タスク名: {{ $task->name }}
</div>
<div>
完了: {{ $task->done ? '完了' : '未' }}
</div>
</div>
<div class="panel-footer">
{{ link_to_route('tasks.index', '戻る') }}
</div>
</div>
@endsection
一覧のリンクから詳細が表示されます。
更新、削除の作成
コントローラにedit, update, destroyアクションを作ります。
public function edit($id)
{
$task = Task::find($id);
return view('tasks/edit')->with('task', $task);
}
public function update(Request $request, $id)
{
$task = Task::find($id);
$task->fill($request->all());
$task->save();
return redirect()->route('tasks.index');
}
public function destroy($id)
{
$task = Task::find($id);
$task->delete();
return redirect()->route('tasks.index');
}
ちなみに、前述のとおりModelで定義しているため、deleteは論理削除になります。
editのViewを作ります。
@extends('layouts.app')
@section('title', "$task->nameの編集")
@section('content')
<div class="panel panel-default">
<div class="panel-heading">
{{ $task->name }}の編集
</div>
<div class="panel-body">
{!! Form::model($task, ['route' => ['tasks.update', $task->id], 'method' => 'patch', 'class' => 'form-horizontal']) !!}
<div class="form-group">
{!! Form::label('name', 'タスク名', ['class' => 'col-sm-3 control-label']) !!}
<div class="col-sm-6">
{!! Form::text('name', $task->name, ['id' => 'task-name', 'class' => 'form-control']) !!}
</div>
</div>
<div class="form-group">
{!! Form::label('done', '完了', ['class' => 'col-sm-3 control-label']) !!}
<div class="col-sm-6">
{!! Form::select('done', [false => '未', true => '完了'], $task->done, ['id' => 'task-done', 'class' => 'form-control']) !!}
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-6">
{!! Form::button('<i class="fa fa-save"></i> 保存', ['type' => 'submit', 'class' => 'btn btn-default']) !!}
</div>
</div>
{!! Form::close() !!}
</div>
<div class="panel-footer">
{{ link_to_route('tasks.index', '戻る') }}
</div>
</div>
@endsection
Formの部分は工夫すればcreateと共通化できそうですね。
ひとまず今回はここまで。
ソースコードはGitHubにアップしてあります。
HisakiEndo/learning_of_laravel