Laravel 5.4: DBマイグレーション
What?
- LaravelでのDBマイグレーションの仕方
Why?
- そもそもなぜDBマイグレーションが必要なのか?
Migration
- 保存場所
database/migrations/
$ php artisan migrate Migration table created successfully. Migrated: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_100000_create_password_resets_table
$ mysql --user=homestead --password=secret homestead mysql> show tables; +---------------------+ | Tables_in_homestead | +---------------------+ | migrations | | password_resets | | users | +---------------------+ 3 rows in set (0.00 sec) mysql> desc migrations; +-----------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------+------------------+------+-----+---------+----------------+ | id | int(10) unsigned | NO | PRI | NULL | auto_increment | | migration | varchar(255) | NO | | NULL | | | batch | int(11) | NO | | NULL | | +-----------+------------------+------+-----+---------+----------------+ 3 rows in set (0.00 sec) mysql> desc users; +----------------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------------+------------------+------+-----+---------+----------------+ | id | int(10) unsigned | NO | PRI | NULL | auto_increment | | name | varchar(255) | NO | | NULL | | | email | varchar(255) | NO | UNI | NULL | | | password | varchar(255) | NO | | NULL | | | remember_token | varchar(100) | YES | | NULL | | | created_at | timestamp | YES | | NULL | | | updated_at | timestamp | YES | | NULL | | +----------------+------------------+------+-----+---------+----------------+ 7 rows in set (0.00 sec) mysql> desc password_resets; +------------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+-------+ | email | varchar(255) | NO | MUL | NULL | | | token | varchar(255) | NO | MUL | NULL | | | created_at | timestamp | YES | | NULL | | +------------+--------------+------+-----+---------+-------+ 3 rows in set (0.00 sec)
Rollback
$ php artisan migrate:status +------+------------------------------------------------+ | Ran? | Migration | +------+------------------------------------------------+ | Y | 2014_10_12_000000_create_users_table | | Y | 2014_10_12_100000_create_password_resets_table | +------+------------------------------------------------+ $ php artisan migrate:rollback Rolled back: 2014_10_12_100000_create_password_resets_table Rolled back: 2014_10_12_000000_create_users_table $ php artisan migrate:status +------+------------------------------------------------+ | Ran? | Migration | +------+------------------------------------------------+ | N | 2014_10_12_000000_create_users_table | | N | 2014_10_12_100000_create_password_resets_table | +------+------------------------------------------------+
Make migration
$ php artisan make:migration create_articles_table --create="articles" Created Migration: 2017_02_14_184315_create_articles_table $ less database/migrations/2017_02_14_184315_create_articles_table.php <?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateArticlesTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('articles', function (Blueprint $table) { // ここから $table->increments('id'); $table->string('title'); $table->text('body'); $table->timestamps(); $table->timestamp('published_at')->useCurrent(); // ここまで追加 }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('articles'); } }
Edit migration
php artisan migrate
mysql> desc articles; +--------------+------------------+------+-----+-------------------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+------------------+------+-----+-------------------+----------------+ | id | int(10) unsigned | NO | PRI | NULL | auto_increment | | title | varchar(255) | NO | | NULL | | | body | text | NO | | NULL | | | created_at | timestamp | YES | | NULL | | | updated_at | timestamp | YES | | NULL | | | published_at | timestamp | NO | | CURRENT_TIMESTAMP | | | exceprt | text | NO | | NULL | | +--------------+------------------+------+-----+-------------------+----------------+ 7 rows in set (0.00 sec)
参考
Laravel 5.4: DBマイグレーションでエラーになる
What?
このバージョンで
laravel vagrant master %$ php artisan --version Laravel Framework 5.4.10 laravel vagrant master %$ mysql --version mysql Ver 14.14 Distrib 5.7.17, for Linux (x86_64) using EditLine wrapper laravel vagrant master %$ php -v PHP 7.1.1-1+deb.sury.org~xenial+1 (cli) (built: Jan 20 2017 09:20:20) ( NTS ) Copyright (c) 1997-2017 The PHP Group Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies with Zend OPcache v7.1.1-1+deb.sury.org~xenial+1, Copyright (c) 1999-2017, by Zend Technologies with blackfire v1.14.3~linux-x64-non_zts71, https://blackfire.io, by Blackfireio Inc.
このmigrationファイルを
/** * Run the migrations. * * @return void */ public function up() { Schema::create('articles', function (Blueprint $table) { // ここから $table->increments('id'); $table->string('title'); $table->text('body'); $table->timestamps(); $table->timestamp('published_at'); // ここまで追加 }); }
migrateすると、エラーになる
$ php artisan migrate [Illuminate\Database\QueryException] SQLSTATE[42000]: Syntax error or access violation: 1067 Invalid default value for 'published_at' (SQL: create table `articles` (`id ` int unsigned not null auto_increment primary key, `title` varchar(255) not null, `body` text not null, `created_at` timestamp nul l, `updated_at` timestamp null, `published_at` timestamp not null) default character set utf8mb4 collate utf8mb4_unicode_ci) [PDOException] SQLSTATE[42000]: Syntax error or access violation: 1067 Invalid default value for 'published_at'
Solution
このmigrationファイルをちょっと書き換え、
/** * Run the migrations. * * @return void */ public function up() { Schema::create('articles', function (Blueprint $table) { // ここから $table->increments('id'); $table->string('title'); $table->text('body'); $table->timestamps(); $table->timestamp('published_at')->useCurrent(); // ここ追加 // ここまで追加 }); }
こうする
$ php artisan migrate:refresh --seed Rolled back: 2014_10_12_100000_create_password_resets_table Rolled back: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_100000_create_password_resets_table Migrated: 2017_02_14_184315_create_articles_table Migrated: 2017_02_23_172823_add_excerpt_to_articles_table
Why?
- マイグレーションを全部ロールバックし、再度実行する力技コマンド
php artisan migrate:refresh --seed
を使って、強制帳消し published_at
がnot null
なのに値が入ってなかったので、useCurrent()
を使って突っ込んだ
失敗例
published_at
だけ触ればいいのに、その前のtimestampも色々いじってしまった結果。
laravel vagrant master %$ php artisan migrate [Symfony\Component\Debug\Exception\FatalThrowableError] Call to a member function useCurrent() on null laravel vagrant master *%$ php artisan migrate [Symfony\Component\Debug\Exception\FatalThrowableError] Call to a member function default() on null laravel vagrant master *%$ php artisan migrate [Symfony\Component\Debug\Exception\FatalThrowableError] Call to a member function nullable() on null
config/database.phpの確認したけど、ちゃんとstrictになってた
'strict' => true,
参考
Laravel 5.4: メンテナンスモードの使い方、仕組み
メンテナンスモードの使い方
- 開始
$ php artisan down
- 復帰
Be right back.
と表示される
php artisan up
メンテナンスモードの仕組み
storage/framework/down
が存在していたらメンテナンスモードになっている
$ ls -la storage/framework/down ls: cannot access 'storage/framework/down': No such file or directory $ php artisan down Application is now in maintenance mode. $ ls -la storage/framework/down -rw-r--r-- 1 vagrant vagrant 66 Feb 14 03:44 storage/framework/down $ php artisan up Application is now live. $ ls -la storage/framework/down ls: cannot access 'storage/framework/down': No such file or directory
- メンテナンスページのテンプレート
vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/views/503.blade.php
にある
TODO
- 部分的にメンテナンスモードにできる?
- あるIPだけ限定でアクセスさせることができる?
参照
Laravel 5.4: 環境設定
DotEnvライブラリ
設定ファイル
.env
: 各環境で使う設定ファイル- git管理対象外
.env.example
: サンプルファイル- git管理対象
$ diff .env.example .env 2c2 < APP_KEY= --- > APP_KEY=base64key...
設定の適用
- 設定ファイルの記述
.env
DB_DATABASE=homestead
- 設定の適用
.env
から値が取れないとき第二引数の値が入る
env('DB_DATABASE', 'foo')
- 設定の更新
storage/framework/config.php
が更新
$ php artisan config:cache
環境名の取得
use App; $environment = App::environment(); // get "local" if (App::environment('local')) { // The environment is local } if (App::environment('local', 'staging')) { // The environment is either local OR staging... }
TODO
- 各環境名の設定方法
- 実際に各環境を立てる
参照
Laravel 5.4: Blade テンプレートを使う
if
@if (count($people)) @endif
foreach
@foreach ($people as $person) {{ $person }} @endforeach
Template
- テンプレート側:
@yield('bar')
- テンプレート利用側:
- Fooテンプレートの継承:
@extends('foo')
- セクション書き換え:
@section('bar')
,@stop
- Fooテンプレートの継承:
- テンプレート:
resources/views/app.blade.php
<body> <div class="container"> @yield('content') </div> @yield('footer') </body>
- テンプレート利用:
resources/views/pages/about.blade.php
@extends('app') @section('content') <h1>About {{$name}}</h1> @if (count($people)) <h3>People I Like:</h3> <ul> @foreach ($people as $person) <li>{{ $person }}</li> @endforeach </ul> @endif @stop
参照
Laravel 5.4: Viewへデータを引き渡す
Summary
- テンプレートはBladeファイル:
foo.blade.php
withを使ってControllerからViewへ渡す
Controller側:
view('pages.about')->with('name', $name)
- View側:
- エスケープ:
{{$bar}}
- 非エスケープ:
{!! $bar !!}
- エスケープ:
How to basic
app/Http/routes.php
Route::get('about', 'PagesController@about');
- コントローラ作成
$ php artisan make:controller PagesController
- aboutメソッド作成
app/Http/Controllers/PagesController.php
class PagesController extends Controller { public function about() { $name = 'Jeffery Way'; return view('pages.about')->with('name', $name); } }
- テンプレート作成
resources/views/pages/about.blade.php
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <h1>About {{$name}}</h1> </body> </html>
How to advance
エスケープ
- エスケープ:
{{$bar}}
- 非エスケープ:
{!! $bar !!}
- エスケープ:
データ渡しにwithを使う
- 単数:
- Controller:
view('pages.about')->with('name', $name)
- Template:
{{$name}}
- Controller:
- 複数(配列):
- Controller:
view('pages.about')->with(['first' => 'Jeffery', 'last' => Way'])
- Template:
{{$first}} {{$last}}
- Controller:
- 単数:
- データ渡しにwithを使わない
- 単数:
- Controller:
view('pages.about', $data)
- Template:
{{$first}} {{$last}}
- Controller:
- 複数(連想配列):
- Controller:
view('pages.about', $data)
- Template:
{{$name['first']}} {{$name['last']}}
- Controller:
- 複数(別変数):
- Controller:
view('pages.about', compact('first', 'last'))
- Template:
{{$first}} {{$last}}
- Controller:
- 単数:
参考
Laravel 5.4: Routing, Controller, Viewの流れを触る
What?
- ざっくり最小のRouting, Controller, Viewの流れを確認する
Why?
- ざっくり最小のものを作りたい
Routing
routes/
: ルーティングディレクトリ- ver 5.3 から
app/Http/routes.php
は廃止
- ver 5.3 から
$ less routes/ api.php channels.php console.php web.php
Route::get('/', 'welcome');
or
Route::get('/', function () { return view('welcome'); });
Controller
app/Http/Controllers/
以下にあるapp/Http/Controllers/WelcomeController.php
<?php namespace App\Http\Controllers; class WelcomeController extends Controller { public function index() { return view('welcome'); } }
View
- blade テンプレートエンジンを使用
resources/views/
以下にあるresources/views/welcome.blade.php
参考
Laravel5 入門 インストールからMVCの基本機能をさっと眺める | hrendoh's memo http://site.oganity.pw/154/