laravelで、2チャンネル・したらば掲示板みたいなBBSの作り方
1, ログイン機能は無し
2, スレ毎にタイトルをつけて、投稿するだけ。編集も削除も無し
3, 投稿は、名前(名無しOK)・投稿テキストのみ。タイムスタンプが付与されるだけ
とりあえず、テーブル定義
#スレ板
php artisan make:migration create_threads_table –create=threads
1 2 3 4 5 6 7 |
Schema::create('threads', function (Blueprint $table) { $table->increments('id'); $table->string('title')->comment('スレのタイトル名'); // 作成日時と更新日時が、自動で入るようにしておく $table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP')); $table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP')); }); |
#投稿内容
php artisan make:migration create_posts_table –create=posts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Schema::create('posts', function (Blueprint $table) { $table->increments('id'); $table->string('name')->default('名無し')->comment('投稿者名'); $table->text('content')->comment('投稿内容'); $table->integer('thread_id')->unsigned()->comment('どのスレの投稿か?'); // 作成日時と更新日時が、自動で入るようにしておく $table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP')); $table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP')); // どのスレの投稿か? $table->foreign('thread_id') ->references('id') ->on('threads') ->onDelete('cascade');// 参照先の親レコードが削除されたら、同時に子レコードも削除する }); |
Seeder.phpで、初期値を設定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public function run() { // スレ板 DB::table('threads')->insert([ 'title' => "テスト用スレ", ]); // 初投稿 DB::table('posts')->insert([ 'thread_id' => 1, 'name' => "テスト用投稿者", 'content' => "初投稿!", ]); DB::table('posts')->insert([ 'thread_id' => 1, // 'name' => "テスト用投稿者", 'content' => "2ゲット!", ]); } |
テーブルのモデルを作る
php artisan make:model Thread
1 2 3 4 5 6 7 8 9 10 11 12 |
class Thread extends Model { // MassAssignment(INSERT/UPDATEで入力できるカラムを指定。$fillable=ホワイトリスト、$guarded=ブラックリスト) protected $guarded = array('id'); // このスレの発言を取得 public function post_list() { return $this->hasMany('App\Post', 'thread_id','id') ->orderBy('created_at'); } } |
php artisan make:model Post
1 2 3 4 5 6 7 8 9 10 11 12 |
class Post extends Model { // MassAssignment(INSERT/UPDATEで入力できるカラムを指定。$fillable=ホワイトリスト、$guarded=ブラックリスト) protected $guarded = array('id'); // 投稿されたら親スレのレコードのupdated_atも更新する(touchesプロパティ) protected $touches = ['thread']; public function thread() { return $this->belongsTo('App\Thread'); } } |
コントローラーを作る –resourceオプションでcrudメソッドを作っておいてもらう
php artisan make:controller ThreadController –resource
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
use App\Thread; class ThreadController extends Controller { // スレ一覧 public function index() { // touchesプロパティにより、新規発言順に並べる $threads = Thread::orderBy('updated_at', 'desc')->get(); return view('threads', compact('threads')); } // スレッドIDから投稿一覧を表示 public function show($id) { $thread = Thread::findOrFail($id); return view('posts', compact('thread')); } // 新規スレ生成 public function store(Request $request) { $rule = [ 'title' => ['required', 'string'], // スレ名 ]; $this->validate($request, $rule); $data = $request->all(); Thread::create($data); return redirect()->to('/thread/'); } } |
php artisan make:controller PostController –resource
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
use App\Post; class PostController extends Controller { public function store(Request $request) { $rule = [ 'thread_id' => ['required'], // スレッドID 'content' => ['required', 'string'], // 投稿内容 ]; $this->validate($request, $rule); $data = $request->all(); if(empty($data['name'])){ $data['name'] = '名無し'; } Post::create($data); return redirect()->to('/thread/' . $data['thread_id']); } } |
画面を作る
thread.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
{{-- 新規投稿 --}} <form method="post" action="/thread"> {{ csrf_field() }} <p> 新規スレ:<input type="text" name="title" value=""></input> <input type="submit" value="作成"></input> </p> </form> <h1>スレッド一覧</h1> @foreach ($threads as $thread) <div> <a href="{{ url('thread/'.$thread->id) }}"> {{ $thread->title }} ({{ count($thread->post_list) }}) {{ $thread->updated_at->format('Y/m/d H:i:s') }} </a> </div> @endforeach |
post.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<a href="/thread">スレッド一覧に戻る</a> <h1>{{$thread->title}}</h1> {{-- 新規投稿 --}} <form method="post" action="/post"> {{ csrf_field() }} <input type="hidden" name="thread_id" value="{{$thread->id}}"></input> <p> 名前:<input type="text" name="name" value=""></input> <input type="submit" value="投稿"></input> </p> <p> 内容:<textarea name="content" rows="4" cols="40"></textarea> </p> </form> {{-- 投稿一覧 --}} @foreach ($thread->post_list as $post) {{ $post->created_at->format('Y/m/d H:i:s') }}({{ $post->name }}) <div> {{-- HTMLタグ無効化してから、改行を<br>変換 --}} {!! nl2br(htmlspecialchars($post->content)) !!} </div> @endforeach |
最後にルーティングを設定すれば完成!
1 2 3 4 5 6 7 8 9 |
<?php // トップページはスレッド一覧 Route::get('/', 'ThreadController@index'); // スレッド関連 Route::resource('/thread', 'ThreadController'); // ポスト関連 Route::resource('/post', 'PostController'); |