メモ > 技術 > フレームワーク: Laravel > 基本的なアプリケーションの作成
基本的なアプリケーションの作成
■テーブル追加
マイグレーションを作成
php artisan make:migration create_articles_table --create=articles
マイグレーションファイルに以下を追加
$table->string('subject');
$table->text('detail');
マイグレーションを実行
php artisan migrate
マイグレーションを巻き戻す場合(最後に「一度に」実行したマイグレーションをまとめて巻き戻す)
php artisan migrate:rollback
以下のテーブルが作成される
CREATE TABLE `articles` (
`id` int(10) UNSIGNED NOT NULL,
`subject` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`detail` text COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
■モデル作成
php artisan make:model Article
■初期値登録(登録する場合)
シーダーを使用する。1件登録するだけなら
/test/database/seeds/DatabaseSeeder.php
にデータ登録コードを追加すればいい
ただし以下のように、Seeder用のファイルを作成するほうがいい
php artisan make:seeder ArticlesTableSeeder
ArticlesTableSeeder.phpに以下を追加
$article = new App\Article;
$article->subject = 'subject:' . str_random(10);
$article->detail = 'detail:' . str_random(50);
$article->save();
もしくは、直接insertしてもいい
use Carbon\Carbon;
$now = Carbon::now();
DB::table('articles')->insert([
'subject' => 'subject:' . str_random(10),
'detail' => 'detail:' . str_random(50),
'created_at' => $now,
'updated_at' => $now,
]);
DatabaseSeeder.phpに以下を追加して、ArticlesTableSeederを呼び出す
$this->call(ArticlesTableSeeder::class);
シーダーを実行する
php artisan db:seed
以下のエラーになる。作成したクラスを参照できていない
[ReflectionException]
Class ArticlesTableSeeder does not exist
require_once で該当クラスを読み込めば参照できるが、Laravelではオートロードの仕組みを使用する
/test/vendor/composer/ 内にオートロードの設定が記載されている
以下のコマンドを実行すると設定が更新され、クラスを参照できるようになる
(存在するはずのクラスを参照できない場合、この方法を試すといい)
composer dump-autoload
また、以下のようにすると特定のシーダーのみ実行できる
php artisan db:seed --class=ArticlesTableSeeder
Laravelで名前空間を指定してオートロードされなかったら見る場所。 - Qiita
http://qiita.com/niiyz/items/5b83ef5255a1ec64d9d6
composer dump-autoloadが面倒くさい Laravel - Qiita
http://qiita.com/ytake/items/98c438d6a006f61df54a
■テーブルの参照例
すべて取得
$articles = DB::table('articles')->get();
$articles = App\Article::all();
ビューでの表示
<ul>
@foreach ($articles as $article)
<li>{{ $article->subject }}</li>
@endforeach
</ul>
追加
$article = new App\Article;
$article->subject = 'Subject';
$article->detail = 'Detail';
$article->save();
更新
$article = App\Article::find(2);
$article->subject = 'Subject2';
$article->detail = 'Detail2';
$article->save();
削除
$article = App\Article::find(2);
$article->delete();
※追加・更新・削除は、fillで複数代入する書き方を推奨(後述)
■モデルの位置を変更する場合
ファイルを移動
\test\app\Article.php
↓
\test\app\Models\Article.php
モデルの呼び出しを変更
$articles = App\Article::all();
↓
$articles = App\Models\Article::all();
モデル内の宣言を変更
namespace App;
↓
namespace App\Models;
■CRUD
\test\routes\web.php
use Illuminate\Http\Request;
/**
* Show Article
*/
Route::get('/article', function () {
return view('article', [
'articles' => App\Article::orderBy('created_at', 'asc')->get()
]);
});
/**
* Add New Article
*/
Route::post('/article', function (Request $request) {
$validator = Validator::make($request->all(), [
'subject' => 'required|max:255',
'detail' => 'required|max:255',
]);
if ($validator->fails()) {
return redirect('/article')
->withInput()
->withErrors($validator);
}
$article = new App\Article;
$article->subject = $request->subject;
$article->detail = $request->detail;
$article->save();
return redirect('/article');
});
/**
* Delete Article
*/
Route::delete('/article/{id}', function ($id) {
App\Article::findOrFail($id)->delete();
return redirect('/article');
});
\test\resources\views\article.blade.php
@extends('layouts.app')
@section('content')
<div class="container">
<div class="col-sm-offset-2 col-sm-8">
<div class="panel panel-default">
<div class="panel-heading">
New Article
</div>
<div class="panel-body">
<!-- Display Validation Errors -->
@if (count($errors) > 0)
<!-- Form Error List -->
<div class="alert alert-danger">
<strong>Whoops! Something went wrong!</strong>
<br><br>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<!-- New Article Form -->
<form action="{{ url('article')}}" method="POST" class="form-horizontal">
{{ csrf_field() }}
<!-- Article Subject -->
<div class="form-group">
<label for="article-subject" class="col-sm-3 control-label">Subject</label>
<div class="col-sm-6">
<input type="text" name="subject" id="article-subject" class="form-control" value="{{ old('subject') }}">
</div>
</div>
<!-- Article Detail -->
<div class="form-group">
<label for="article-detail" class="col-sm-3 control-label">Detail</label>
<div class="col-sm-6">
<input type="text" name="detail" id="article-detail" class="form-control" value="{{ old('detail') }}">
</div>
</div>
<!-- Add Article Button -->
<div class="form-group">
<div class="col-sm-offset-3 col-sm-6">
<button type="submit" class="btn btn-default">
<i class="fa fa-btn fa-plus"></i>Add Article
</button>
</div>
</div>
</form>
</div>
</div>
<!-- Current Articles -->
@if (count($articles) > 0)
<div class="panel panel-default">
<div class="panel-heading">
Current Articles
</div>
<div class="panel-body">
<table class="table table-striped article-table">
<thead>
<th>Article</th>
<th> </th>
</thead>
<tbody>
@foreach ($articles as $article)
<tr>
<td class="table-text"><div>{{ $article->subject }}: {{ $article->detail }}</div></td>
<!-- Article Delete Button -->
<td>
<form action="{{ url('article/'.$article->id) }}" method="POST">
{{ csrf_field() }}
{{ method_field('DELETE') }}
<button type="submit" class="btn btn-danger">
<i class="fa fa-btn fa-trash"></i>Delete
</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endif
</div>
</div>
@endsection
■CRUD:コントローラーを使用する場合
Route::get('/article', 'ArticleController@index');
Route::post('/article', 'ArticleController@store');
Route::delete('/article/{article}', 'ArticleController@destroy');
\test\app\Http\Controllers\ArticleController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Article;
class ArticleController extends Controller
{
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Display a list of all of the user's article.
*
* @param Request $request
* @return Response
*/
public function index(Request $request)
{
return view('article', [
'articles' => Article::orderBy('created_at', 'asc')->get()
]);
}
/**
* Create a new article.
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
$validator = $this->validate($request, [
'subject' => 'required|max:255',
'detail' => 'required|max:255',
]);
$article = new Article;
$article->subject = $request->subject;
$article->detail = $request->detail;
$article->save();
return redirect('/article');
}
/**
* Destroy the given article.
*
* @param Request $request
* @param string $id
* @return Response
*/
public function destroy(Request $request, $id)
{
Article::findOrFail($id)->delete();
return redirect('/article');
}
}
■基本的なバリデーションについて
$this->validate() を呼ぶことにより、エラーがあれば $errors にエラーメッセージが格納される
Validator::make() と $this->validate() の違いについても、以下のページで触れられている
実際のアプリケーションでは、フォームリクエストの仕組みでバリデーションする方が良さそう
バリデーション 5.4 Laravel
https://readouble.com/laravel/5.4/ja/validation.html
Laravelバリデーション指南書:フォームリクエストを使おう - Qiita
http://qiita.com/sakuraya/items/abca057a424fa9b5a187
Laravel5.0:FormRequestを使ったValidation - メドピア開発者ブログ
http://tech.medpeer.co.jp/entry/2015/06/16/171115
Laravel 5.1 入門記 その14(Form Request とメッセージのカスタマイズ編) - 日記
http://tnamao.hatenablog.com/entry/2015/10/04/175345