前回の続き。
インスパイヤ元: インスパイヤされて掲示板を作りたくなった(2)
テーブルを作ろう
テーブルについては 元ネタ を参照。以下のテーブルを作成しよう。
- boards
- threads
- posts
いらないファイルを消そう
databases/migration の 2014_10_12_000000_create_users_table.php と 2014_10_12_100000_create_password_resets_table.php を消しましょう。これは、Laravel の認証に使用するテーブルのマイグレーションファイルですが、今回は必要ないと思います(多分)。
boards テーブルを作ろう
$ php artisan make:migration create_boards_table --create=boards
とすると boards テーブルを作成するマイグレーションファイルが出来上がります。--create オプションが肝1です。
生成されたマイグレーションファイルはこんな感じ。
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateBoardsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('boards', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('boards');
}
}
マイグレーションファイルには up メソッドと down メソッドが定義されていて up メソッドは migrate コマンド(後述) を実行した時に呼び出されるメソッドで down メソッドは migrate:rollback コマンドを実行した時に呼び出されます。このままで migrate コマンドを実行するとこんな感じの SQL が発行されます。
$ php artisan migrate --pretend
Migration table created successfully.
CreateBoardsTable: create table "boards" ("id" varchar not null, "name" varchar not null, "txt" varchar not null, primary key ("id"))
boards テーブルにオートインクリメントされる id という名前のプライマリキーと datetime 型の created_at と updated_at というカラムが作成されるのがわかりますね。
id カラムは $table->increments('id') 、 created_at と updated_at は $table->timestamps() に対応してます。今回はインスパイヤ元に従ってにいきます。そういったサンプルがあんまりないのでいいかな、と。
ではテーブルを定義していきましょう。まずは boards テーブル。up メソッドだけ抜粋。
<?php
class CreateBoardsTable extends Migration
{
public function up()
{
Schema::create('boards', function (Blueprint $table) {
$table->string('id')->primary();
$table->string('name');
$table->string('txt');
});
}
}
次は threads テーブル。
コマンド叩いて…
$ php artisan make:migration create_threads_table --create=threads
マイグレーションファイル作って…こう書く。
<?php
class CreateThreadsTable extends Migration
{
public function up()
{
Schema::create('threads', function (Blueprint $table) {
$table->integer('timestamp');
$table->string('board_id');
$table->string('title');
$table->primary(['timestamp', 'board_id']);
});
}
}
複合主キーも定義できます。とはいえ、前述した Eloquent は複合主キーをサポートしていないのでクエリービルダーという Eloquent の基盤になっている仕組みを使うことになります。
最後に posts テーブル。
$ php artisan make:migration create_posts_table --create=posts
<?php
class CreatePostsTable extends Migration
{
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
// 元エントリは INT ってなっているけど、多分 string
$table->string('board_id');
$table->integer('thread_timestamp');
$table->string('posted_at');
$table->string('name');
$table->string('email');
$table->string('author_hash');
$table->string('message');
$table->string('ip_addr');
$table->index(['board_id', 'thread_timestamp'], 'post_board_thread');
$table->index('author_hash', 'post_author_hash');
});
}
}
こんな感じで index も定義できる。
SQL を確認しよう。--pretend オプション便利。
$ php artisan migrate --pretend
CreateBoardsTable: create table "boards" ("id" varchar not null, "name" varchar not null, "txt" varchar not null, primary key ("id"))
CreateThreadsTable: create table "threads" ("timestamp" integer not null, "board_id" varchar not null, "title" varchar not null, primary key ("timestamp", "board_id"))
CreatePostsTable: create table "posts" ("id" integer not null primary key autoincrement, "board_id" varchar not null, "thread_timestamp" integer not null, "posted_at" varchar not null, "name" varchar not null, "email" varchar not null, "author_hash" varchar not null, "message" varchar not null, "ip_addr" varchar not null)
CreatePostsTable: create index post_board_thread on "posts" ("board_id", "thread_timestamp")
CreatePostsTable: create index post_author_hash on "posts" ("author_hash")
うむ。よさげだ。では実行。
$ php artisan migrate
Migrated: 2016_03_01_120922_create_boards_table
Migrated: 2016_03_01_125931_create_threads_table
Migrated: 2016_03_01_130821_create_posts_table
できた。楽ちん。
シードデータをつっこんでみる
php artisan make:seeder {name} でシードクラス作れるんですが、量も少ないので database/seeds/DatabaseSeeder.php に直接書いちゃいましょう。
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
DB::table('boards')->insert([
'id' => 'gline',
'name' => 'ガイドライン@インスパイヤー',
'txt' => 'ここがガ板ですよ。。。',
]);
DB::table('threads')->insert([
'timestamp' => 123456789,
'board_id' => 'gline',
'title' => 'インスパイヤのガイドライン',
]);
$now = \Carbon\Carbon::now();
DB::table('posts')->insert([
[
'board_id' => 'gline',
'thread_timestamp' => 123456789,
'posted_at' => $now,
'name' => 'たっどさん',
'email' => '#いんすぱいやー',
'author_hash' => 'tW1nDri11',
'message' => 'てすとです…',
'ip_addr' => '127.0.0.1',
],
[
'board_id' => 'gline',
'thread_timestamp' => 123456789,
'posted_at' => $now,
'name' => 'たっどさん',
'email' => '#いんすぱいやー',
'author_hash' => 'tW1nDri11',
'message' => 'もういい加減ねるぽ',
'ip_addr' => '127.0.0.1',
],
]);
}
}
一目瞭然な簡潔なコードですね。posts テーブルの posted_at のために Carbon という日時を扱う便利なライブラリを使ってるのと posts テーブルのインサートで2レコード一気にいれてます。ちなみにこう書くとバルクインサートになるので、覚えておくのがよいです。
$ php artisan db:seed
画面を作ろう
Laravel には Blade というテンプレートエンジンがあってですね、これがなかなか便利です。PhpStorm つかうともっと便利2です。
共通点プレートを作ろう
Laravel の View は resources/views に作ります。Blade も Twig と同じようにテンプレートの継承ができるので、まずはテンプレートファイルから作りましょう。コマンドがないので手動でつくります。Blade を使う場合は .blade.php という拡張子(といっていいんだろうか)になります。
<!doctype html>
<html lang="ja">
<head>
<title>@yield('title', 'いんすぱいやーBBS')</title>
</head>
<body>
@yield('content')
@section('footer')
<hr>
<footer>
<address>
© Copyright 2016 localdisk<br>
<a href="https://github.com/localdisk/inspire-bbs">InspireBBS Laravel</a> is licenced under <a href="http://www.wtfpl.net/"><abbr title="Do What the Fuck You Want to Public License">WTFPL</abbr></a> and/or <a href="http://www.gnu.org/licenses/agpl-3.0.html"><abbr title="GNU Affero General Public License, Version 3">AGPLv3</abbr></a>
</address>
</footer>
@show
</body>
</html>
@yield と @section というディレクティブに注目。Twig と大体考え方は一緒だと思います。多分。詳しくはBladeテンプレート 5.1 Laravelを参照してください(疲れた)
個別ページを作ろう
先ほど作った default.blade.php を継承した index.blade.php を作ります。
@extends('layouts.default')
@section('title', 'いんすぱいやーBBSへようこそ')
@section('content')
<h1>いんすぱいやーBBS</h1>
<p>ヾ(〃><)ノ゙< {{ $greeting }}</p>
@stop
-
@extends('layouts.default')と書くことで、layouts/default.blade.phpを継承 -
@sectionのtitleとcontentに定義を書く -
{{ $greeting }}で変数を出力
タイムゾーンの定義
タイムゾーンを設定します。Laravel はデフォルトで UTC にタイムゾーンを設定しているので Asia/Tokyo に設定し直すには config/app.php を変更します。まぁ、実際のところは UTC のままで、表示の際に Carbon 使ったり、Moment Timezone あたりを使って JST に変換したりすると思います。
<?php
return [
'timezone' => 'Asia/Tokyo',
]
元気に挨拶をしつつ画面に表示しよう
疲れたので巻きに入ります。Laravel は app/Http/routes.php にルート定義をします。その中で書くもよし、コントローラーを作るもよし。今回は routes.php に直接書いちゃいましょう。
<?php
Route::get('/', function () {
$hour = Carbon\Carbon::now()->hour;
$greeting = null;
if (4 <= $hour && $hour < 10) {
$greeting = "お早うございます";
} elseif (10 <= $hour && $hour < 17) {
$greeting = "こんにちは";
} else {
$greeting = "こんばんわ";
}
return view('index', compact('greeting'));
});
まとめ
いろいろ説明を省略しすぎている感じがあるので元記事を読んでからこっち読んでみてください。(:3」∠)
追記
続きを書いた。Laravel で掲示板作りたくなった(3)