【保存版】Laravelで掲示板を作成する方法【チュートリアル】
Laravelで掲示板を作成する方法をまとめました。
当記事をマスターすることで、2チャンネルのような掲示板を作れるようになります。
類似記事も書いています。以下の記事のほうが難易度が高いです。
LaravelでCMSを作成する方法【チュートリアル】
Laravelでつくる掲示板の仕様
- 投稿一覧の表示
- 単一投稿の表示
- コメントの表示
- 特定カテゴリーに属する記事一覧の表示
Laravelでつくる掲示板のイメージ
スクリーンショットでご紹介します。
投稿一覧の表示
投稿記事の表示
投稿ページ
投稿のバリデーション
コメント投稿/表示/バリデーション
当記事をとおして得られる知識
- Laravelの初期設定
- マイグレーションの方法
- モデルのリレーション(hasMany, belongsTo)方法
- Laravelのシード機能
- リソースコントローラーの使い方
- CRUD処理
では、まとめていきます。
Laravelの初期セットアップ
Laravelをインストールします
$ composer create-project laravel/laravel bbc --prefer-dist
DB接続の設定をする
編集ファイル:app/config/database.php
'mysql' => array(
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'bbc',
'username' => 'root',
'password' => 'root',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
デバッグ機能を有効化する
編集ファイル:app/config/app.php
'debug' => true,
マイグレーションでDBを作成する
1. ポストテーブル
$ php artisan migrate:make create_posts_table
2. カテゴリーテーブル
$ php artisan migrate:make create_categories_table
3. コメントテーブル
$ php artisan migrate:make create_comments_table
※Laravelの規約に従うために、データベース名は必ず複数形にします。
マイグレーションで生成されたファイルにカラムの情報を書き込む
編集ファイル:app/database/migrations/2014_12_00_000000_create_posts_table
<?php
use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;
class CreatePostsTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('posts', function($table){
$table->increments('id');
$table->string('title');
$table->string('cat_id'); // ポストテーブルとカテゴリーテーブルの紐付けに利用します
$table->text('content');
$table->unsignedInteger('comment_count'); // 投稿に何件のコメントがついたのかをカウントします
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('posts');
}
}
編集ファイル:app/database/migrations/2014_12_00_000000_create_categories_table
<?php
use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;
class CreateCategoriesTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('categories', function($table){
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('categories');
}
}
編集ファイル:app/database/migrations/2014_12_00_000000_create_commets_table
<?php
use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;
class CreateCommentsTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('comments', function($table){
$table->increments('id');
$table->unsignedInteger('post_id'); // ポストテーブルとコメントテーブルの紐付けに利用します
$table->string('commenter');
$table->text('comment');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('comments');
}
}
マイグレーションを実行する
$ php artisan migrate
モデルのリレーションを設定する
以下、3つのファイルを作成します。
新規作成ファイル:app/models/Post.php
<?php
class Post extends Eloquent{
public function Comments(){
// 投稿はたくさんのコメントを持つ
return $this->hasMany('Comment', 'post_id');
}
public function Category(){
// 投稿は1つのカテゴリーに属する
return $this->belongsTo('Category','cat_id');
}
}
新規作成ファイル:app/models/Category.php
<?php
class Category extends Eloquent{}
新規作成ファイル:app/models/Comments.php
<?php
class Comment extends Eloquent{}
LaravelのSeed機能を使ってDBにダミーデータを送信する
新規作成ファイル:app/database/seeds/PostCommentSeeder.php
<?php
class PostCommentSeeder extends Seeder{
public function run(){
$content = 'この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。';
$commentdammy = 'コメントダミーです。ダミーコメントだよ。';
for( $i = 1 ; $i <= 10 ; $i++) {
$post = new Post;
$post->title = "$i 番目の投稿";
$post->content = $content;
$post->cat_id = 1;
$post->save();
$maxComments = mt_rand(3, 15);
for ($j=0; $j <= $maxComments; $j++) {
$comment = new Comment;
$comment->commenter = '名無しさん';
$comment->comment = $commentdammy;
// モデル(Post.php)のCommentsメソッドを読み込み、post_idにデータを保存する
$post->comments()->save($comment);
$post->increment('comment_count');
}
}
// カテゴリーを追加する
$cat1 = new Category;
$cat1->name = "電化製品";
$cat1->save();
$cat2 = new Category;
$cat2->name = "食品";
$cat2->save();
}
}
以下のコマンドで実行します。
$ php artisan db:seed --class= PostCommentSeeder
リソースコントローラーを生成する
$ php artisan controller:make PostsController
つぎに、以下のようにルーティングの設定をしておきます。
編集ファイル:app/routes.php
Route::resource('bbc', 'PostsController');
※hogehoge.com/bbcにアクセスすることでリソースコントローラーが実行されます。
投稿記事を表示するためのコントローラーをつくっていく
投稿一覧の表示ページを作成する
編集ファイル:app/controller/PostsController.php
public function index()
{
$posts = Post::all();
return View::make('bbc.index')->with('posts', $posts);
}
つぎに、ビューを作ります。
まずは、マスターテンプレートを作成します。
新規作成ファイル:app/views/layouts/default.blade.php
<!DOCTYPE HTML>
<html lang="ja">
<head>
<meta charset="utf-8" />
<!-- bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap-theme.min.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<title>Laravelの掲示板</title>
</head>
<body>
@yield('content')
</body>
</html>
では、投稿一覧を表示してみます。
新規作成ファイル:app/bbc/index.blade.php
@extends('layouts.default')
@section('content')
<div class="col-xs-8 col-xs-offset-2">
@foreach($posts as $post)
<h2>タイトル:{{ $post->title }}
<small>投稿日:{{ date("Y年 m月 d日",strtotime($post->created_at)) }}</small>
</h2>
<p>カテゴリー:{{ $post->category->name }}</p>
<p>{{ $post->content }}</p>
<p>{{ link_to("/bbc/{$post->id}", '続きを読む', array('class' => 'btn btn-primary')) }}</p>
<p>コメント数:{{ $post->comment_count }}</p>
<hr />
@endforeach
</div>
@stop
※$post->category->nameに関して
Post.phpモデルのCategory()メソッドからカテゴリー名を取得しています。
Eloquent ORMの便利な機能です。
以上で、以下のようなページが完成します。
URLは、hogehoge.com/bbcとなります。
続きを読むボタンを作っていく
現状では、続きを読むボタンは動きません。
続きを読むボタンを動かすためにコントローラーを作ります。
編集ファイル:app/controller/PostsController.php
public function show($id)
{
$post = Post::find($id);
return View::make('bbc.single')->with('post', $post);
}
つぎにビューをつくります。
新規に作成ファイル:app/views/bbc/single.blade.php
@extends('layouts.default')
@section('content')
<div class="col-xs-8 col-xs-offset-2">
<h2>タイトル:{{ $post->title }}
<small>投稿日:{{ date("Y年 m月 d日",strtotime($post->created_at)) }}</small>
</h2>
<p>カテゴリー:{{ $post->category->name }}</p>
<p>{{ $post->content }}</p>
<hr />
<h3>コメント一覧</h3>
@foreach($post->comments as $single_comment)
<h4>{{ $single_comment->commenter }}</h4>
<p>{{ $single_comment->comment }}</p><br />
@endforeach
</div>
@stop
投稿機能を作成する
まずはビューをつくります。
新規作成ファイル:app/views/bbc/create.blade.php
@extends('layouts.default')
@section('content')
<div class="col-xs-8 col-xs-offset-2">
<h1>投稿ページ</h1>
{{-- 投稿完了時にフラッシュメッセージを表示 --}}
@if(Session::has('message'))
<div class="bg-info">
<p>{{ Session::get('message') }}</p>
</div>
@endif
{{-- エラーメッセージの表示 --}}
@foreach($errors->all() as $message)
<p class="bg-danger">{{ $message }}</p>
@endforeach
{{ Form::open(['route' => 'bbc.store'], array('class' => 'form')) }}
<div class="form-group">
<label for="title" class="">タイトル</label>
<div class="">
{{ Form::text('title', null, array('class' => '')) }}
</div>
</div>
<div class="form-group">
<label for="cat_id" class="">カテゴリー</label>
<div class="">
<select name="cat_id" type="text" class="">
<option></option>
<option value="1" name="1">電化製品</option>
<option value="2" name="2">食品</option>
</select>
</div>
</div>
<div class="form-group">
<label for="content" class="">本文</label>
<div class="">
{{ Form::textarea('content', null, array('class' => '')) }}
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">投稿する</button>
</div>
{{ Form::close() }}
</div>
@stop
つぎに、フォームのバリデーションとDBへの保存機能をつくります。
編集ファイル:app/controllers/PostsController.php
public function store()
{
$rules = [
'title' => 'required',
'content'=>'required',
'cat_id' => 'required',
];
$messages = array(
'title.required' => 'タイトルを正しく入力してください。',
'content.required' => '本文を正しく入力してください。',
'cat_id.required' => 'カテゴリーを選択してください。',
);
$validator = Validator::make(Input::all(), $rules, $messages);
if ($validator->passes()) {
$post = new Post;
$post->title = Input::get('title');
$post->content = Input::get('content');
$post->cat_id = Input::get('cat_id');
$post->save();
return Redirect::back()
->with('message', '投稿が完了しました。');
}else{
return Redirect::back()
->withErrors($validator)
->withInput();
}
}
これで完成です。
バリデーションエラーがおきると以下のようになります。
特定のカテゴリーに属する記事一覧が表示できるようにする
まずはビューをつくります。
編集ファイル:app/views/bbc/index.blade.php
<!-- <p>カテゴリー:{{ $post->category->name }}</p> -->
<p>{{ link_to("/category/{$post->category->id}", $post->category->name, array('class' => '')) }}</p>
</code></pre>
これで、カテゴリーをクリックできるようになります。
つぎにコントローラーを作成します。
編集ファイル:app/controller/PostController.php
<pre><code class="language-php">
public function showCategory($id)
{
$category_posts = Post::where('cat_id', $id)->get();
return View::make('category')
->with('category_posts', $category_posts);
}
</code></pre>
つぎに、ビューをつくります。
新規作成ファイル:app/views/bbc/category.blade.php
<pre><code class="language-php">
@extends('layouts.default')
@section('content')
<div class="col-xs-8 col-xs-offset-2">
@foreach($category_posts as $category_post)
<h2>タイトル:{{ $category_post->title }}
<small>投稿日:{{ date("Y年 m月 d日",strtotime($category_post->created_at)) }}</small>
</h2>
<p>{{ $category_post->content }}</p>
<p>{{ link_to("/bbc/{$category_post->id}", '続きを読む', array('class' => 'btn btn-primary')) }}</p>
<p>コメント数:{{ $category_post->comment_count }}</p>
<hr />
@endforeach
</div>
@stop
以上で、特定カテゴリーに属する記事の一覧ページが完成しました。
コメントの投稿機能を作成する
まずは。コメントのビューを作成します。
編集ファイル:app/views/bbc/single.blade.php
@extends('layouts.default')
@section('content')
<div class="col-xs-8 col-xs-offset-2">
<h2>タイトル:{{ $post->title }}
<small>投稿日:{{ date("Y年 m月 d日",strtotime($post->created_at)) }}</small>
</h2>
<p>カテゴリー:{{ $post->category->name }}</p>
<p>{{ $post->content }}</p>
<hr />
<h3>コメント一覧</h3>
@foreach($post->comments as $single_comment)
<h4>{{ $single_comment->commenter }}</h4>
<p>{{ $single_comment->comment }}</p><br />
@endforeach
<h3>コメントを投稿する</h3>
{{-- 投稿完了時にフラッシュメッセージを表示 --}}
@if(Session::has('message'))
<div class="bg-info">
<p>{{ Session::get('message') }}</p>
</div>
@endif
{{-- エラーメッセージの表示 --}}
@foreach($errors->all() as $message)
<p class="bg-danger">{{ $message }}</p>
@endforeach
{{ Form::open(['route' => 'comment.store'], array('class' => 'form')) }}
<div class="form-group">
<label for="commenter" class="">名前</label>
<div class="">
{{ Form::text('commenter', null, array('class' => '')) }}
</div>
</div>
<div class="form-group">
<label for="comment" class="">コメント</label>
<div class="">
{{ Form::textarea('comment', null, array('class' => '')) }}
</div>
</div>
{{ Form::hidden('post_id', $post->id) }}
<div class="form-group">
<button type="submit" class="btn btn-primary">投稿する</button>
</div>
{{ Form::close() }}
</div>
@stop
つぎにコントローラーを作成します。
$ php artisan controller:make CommentsController
生成されたファイルに以下の記述します。
public function store()
{
$rules = [
'commenter' => 'required',
'comment'=>'required',
];
$messages = array(
'commenter.required' => 'タイトルを正しく入力してください。',
'comment.required' => '本文を正しく入力してください。',
);
$validator = Validator::make(Input::all(), $rules, $messages);
if ($validator->passes()) {
$comment = new Comment;
$comment->commenter = Input::get('commenter');
$comment->comment = Input::get('comment');
$comment->post_id = Input::get('post_id');
$comment->save();
return Redirect::back()
->with('message', '投稿が完了しました。');
}else{
return Redirect::back()
->withErrors($validator)
->withInput();
}
}
さいごにルーティングの設定をします。
編集ファイル:app/routes.php
Route::resource('comment', 'CommentsController');
以上で掲示板が完成しました( ՞ٹ՞)
おわりに…
Laravelで掲示板を作成するチュートリアルがネット上になかったので作成してみました。
すこしでも記事が役に立てば幸いです。
コードの間違いなどありましたらご連絡いただけると助かります。
質問などはTwitterでうけつけます。