目次
はじめに
本記事は、Laravelの学習のために実際に掲示板を作るチュートリアルです。Laravelを使ってレイアウトを組んだり、データベースを操作する基本が身につきます。
当記事は【保存版】Laravelで掲示板を作成する方法【チュートリアル】を参考にしています。
作るもの
準備
以下のコードをblog.cssとしてpublic/css以下においてください。
/* stylelint-disable selector-list-comma-newline-after */
.blog-header {
line-height: 1;
border-bottom: 1px solid #e5e5e5;
padding: 8px 30px
}
.blog-header-logo {
font-family: "Playfair Display", Georgia, "Times New Roman", serif;
font-size: 2.25rem;
}
.blog-header-logo:hover {
text-decoration: none;
}
h1, h2, h3, h4, h5, h6 {
font-family: "Playfair Display", Georgia, "Times New Roman", serif;
}
.container {
margin-top: 20px
}
.display-4 {
font-size: 2.5rem;
}
@media (min-width: 768px) {
.display-4 {
font-size: 3rem;
}
}
.nav-scroller {
position: relative;
z-index: 2;
height: 2.75rem;
overflow-y: hidden;
}
.nav-scroller .nav {
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: nowrap;
flex-wrap: nowrap;
padding-bottom: 1rem;
margin-top: -1px;
overflow-x: auto;
text-align: center;
white-space: nowrap;
-webkit-overflow-scrolling: touch;
}
.nav-scroller .nav-link {
padding-top: .75rem;
padding-bottom: .75rem;
font-size: .875rem;
}
.card-img-right {
height: 100%;
border-radius: 0 3px 3px 0;
}
.flex-auto {
-ms-flex: 0 0 auto;
flex: 0 0 auto;
}
.h-250 { height: 250px; }
@media (min-width: 768px) {
.h-md-250 { height: 250px; }
}
/*
* Blog name and description
*/
.blog-title {
margin-bottom: 0;
font-size: 2rem;
font-weight: 400;
}
.blog-description {
font-size: 1.1rem;
color: #999;
}
@media (min-width: 40em) {
.blog-title {
font-size: 3.5rem;
}
}
/* Pagination */
.blog-pagination {
margin-bottom: 4rem;
}
.blog-pagination > .btn {
border-radius: 2rem;
}
/*
* Blog posts
*/
.blog-post {
margin-bottom: 4rem;
}
.blog-post-title {
margin-bottom: .25rem;
font-size: 2.5rem;
}
.blog-post-meta {
margin-bottom: 1.25rem;
color: #999;
}
/*
* Footer
*/
.blog-footer {
padding: 2.5rem 0;
color: #999;
text-align: center;
background-color: #f9f9f9;
border-top: .05rem solid #e5e5e5;
}
.blog-footer p:last-child {
margin-bottom: 0;
}
プロジェクト作成
composer create-project laravel/laravel --prefer-dist board
モデルとマイグレーションファイルを作成する
まずは以下のコマンドを打ち込んでモデルとマイグレーションファイルの雛形を作成します。
php artisan make:model Post -m
php artisan make:model Category -m
php artisan make:model Comment -m
すると、以下のようなモデルが作成されます。
Post.php
Category.php
Comment.php
また、database/migrations以下に以下のようなマイグレーションファイルが作成されます。
- 2018_XX_XX_XXXXXX_create_posts_table.php
- 2018_XX_XX_XXXXXX_create_categories_table.php
- 2018_XX_XX_XXXXXX_create_comments_table.php
マイグレーションファイルを書き上げる
database/migrations/
XXXXXX_create_posts_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePostsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->unsignedInteger('category_id');
$table->text('content');
$table->unsignedInteger('comment_count');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
}
database/migrations/
XXXXXX_create_categories_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCategoriesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('categories');
}
}
database/migrations/
XXXXXX_create_comments_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCommentsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('post_id');
$table->string('commenter');
$table->text('comment');
$table->unsignedInteger('comment_count')->default(0);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('comments');
}
}
php artisan migrate
モデルファイルを書き上げる
作成した3つのモデルのリレーションを定義します。
app/Post.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function Comments() {
// 1つの投稿は複数のコメントを所有する
return $this->hasMany('App\Comment');
}
public function Category(){
// 1つの投稿は1つのカテゴリーに所属する
return $this->belongsTo('App\Category');
}
}
app/Category.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
//
}
app/Comment.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
//
}
シーダーを作成する
シーダとはデータベースにあらかじめ必要なデータ(今回はダミーデータ)を入れる機能のことです。
以下のコマンドを実行してシーダファイルを作成します。
php artisan make:seeder PostCommentSeeder
database/seeds/にPostCommentSeeder.phpが作成されます。以下のようにシーダを書き上げましょう。
<?php
use Illuminate\Database\Seeder;
use App\Post;
use App\Category;
use App\Comment;
class PostCommentSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$content = 'この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。';
$commentdammy = 'コメントです。';
for( $i = 1 ; $i <= 10 ; $i++) {
$post = new Post;
$post->title = "$i 番目の投稿";
$post->content = $content;
$post->category_id = 1;
$post->save();
$maxComments = mt_rand(3, 15);
for ($j=0; $j <= $maxComments; $j++) {
$comment = new Comment;
$comment->commenter = 'テストユーザ';
$comment->comment = $commentdammy;
$post->comments()->save($comment);
$post->increment('comment_count');
}
}
$cat1 = new Category;
$cat1->name = "カテゴリーその1";
$cat1->save();
$cat2 = new Category;
$cat2->name = "カテゴリーその2";
$cat2->save();
}
書き上げたら以下のコマンドを実行しましょう。
php artisan db:seed --class= PostCommentSeeder
ダミーデータが作成できました!
コントローラを作成する
以下のコマンドを実行してコントローラを作成しましょう。
php artisan make:controller PostController --resource --model=Post
実行するとapp/Http/ControllersにPostController.phpが作成されます。
ルーティングを設定する
routes/web.phpに以下を書きます。
Route::resource('posts', 'PostController');
リソースコントローラにより処理されるアクション
動詞 | URI | アクション |
---|---|---|
GET | /photos | index |
GET | /photos/create | create |
POST | /photos | store |
GET | /photos/{photo} | show |
GET | /photos/{photo}/edit | edit |
PUT/PATCH | /photos/{photo} | update |
DELETE | /photos/{photo} | destroy |
投稿記事を表示する
投稿一覧を表示する
app/Http/Controllers/PostController.phpを編集します。
public function index()
{
$posts = Post::all();
return view('board.index', ['posts' => $posts]);
}
次に、resources/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/4.1.3/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="{{ asset('/css/blog.css') }}">
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
<title>Laravelの掲示板</title>
</head>
<body>
<header class="blog-header py-3">
<div class="row flex-nowrap justify-content-between align-items-center">
<div class="col-4 text-center">
<a class="blog-header-logo text-dark" href="#">Laravelの掲示板</a>
</div>
<div class="col-4 d-flex justify-content-end align-items-center">
<a class="text-muted" href="#">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="mx-3"><circle cx="10.5" cy="10.5" r="7.5"></circle><line x1="21" y1="21" x2="15.8" y2="15.8"></line></svg>
</a>
<a class="btn btn-sm btn-outline-secondary" href="#">Sign up</a>
</div>
</div>
</header>
<div class="container">
@yield('content')
</div>
</body>
</html>
その後、resources/views/board配下にindex.blade.phpというファイルを作成し、以下のように書き上げましょう。
@extends('layouts.default')
@section('content')
@if(session('message'))
<div class="bg-info">
<p>{{ session('message') }}</p>
</div>
@endif
{{-- エラーメッセージの表示 --}}
@foreach($errors->all() as $message)
<p class="bg-danger">{{ $message }}</p>
@endforeach
<div class="col-xs-8 col-xs-offset-2">
<div class="card mb-4 shadow-sm">
<div class="card-body">
<h2>タイトル:{{ $post->title }}</h2>
<div class="d-flex justify-content-between align-items-center">
<div class="btn-group">
<a class="btn btn-sm btn-outline-secondary">カテゴリー:{{ $post->category->name }}</a>
</div>
<small class="text-muted">{{date("Y年 m月 d日",strtotime($post->created_at))}}</small>
</div>
</div>
</div>
<p>{{ $post->content }}</p>
<hr />
<h3>コメント一覧</h3>
@foreach($post->comments as $single_comment)
<div class="card mb-4 shadow-sm">
<div class="card-body">
<h4>{{ $single_comment->commenter }}</h4>
<div class="d-flex justify-content-between align-items-center">
<p>{{ $single_comment->comment }}</p>
<small class="text-muted">{{date("Y年 m月 d日",strtotime($single_comment->created_at))}}</small>
</div>
</div>
</div>
@endforeach
@stop
書き上げたら、/postsのurlにアクセスしてみてください。うまく表示されていれば成功です!
投稿詳細を表示する
先ほどと同じようにapp/Http/Controllers/PostController.phpを編集します。
public function show(Post $post)
{
return view('board.single',['post' => $post]);
}
その後、resources/views/board配下にsingle.blade.phpというファイルを作成し、以下のように書き上げましょう。
@extends('layouts.default')
@section('content')
@if(session('message'))
<div class="bg-info">
<p>{{ session('message') }}</p>
</div>
@endif
{{-- エラーメッセージの表示 --}}
@foreach($errors->all() as $message)
<p class="bg-danger">{{ $message }}</p>
@endforeach
<div class="col-xs-8 col-xs-offset-2">
<div class="card mb-4 shadow-sm">
<div class="card-body">
<h2>タイトル:{{ $post->title }}</h2>
<div class="d-flex justify-content-between align-items-center">
<div class="btn-group">
<a class="btn btn-sm btn-outline-secondary">カテゴリー:{{ $post->category->name }}</a>
</div>
<small class="text-muted">{{date("Y年 m月 d日",strtotime($post->created_at))}}</small>
</div>
</div>
</div>
<p>{{ $post->content }}</p>
<hr />
<h3>コメント一覧</h3>
@foreach($post->comments as $single_comment)
<div class="card mb-4 shadow-sm">
<div class="card-body">
<h4>{{ $single_comment->commenter }}</h4>
<div class="d-flex justify-content-between align-items-center">
<p>{{ $single_comment->comment }}</p>
<small class="text-muted">{{date("Y年 m月 d日",strtotime($single_comment->created_at))}}</small>
</div>
</div>
</div>
@endforeach
@stop
書き上げたら、/posts/1のurlにアクセスしてみてください。うまく表示されていれば先ほどと同様成功です!
投稿できるようにする
まず、app/Http/Controllers/PostController.phpを編集して投稿ロジックを組み立てます。
public function store(Request $request)
{
$rules = [
'title' => 'required',
'content'=>'required',
'category_id' => 'required',
];
$messages = array(
'title.required' => 'タイトルを正しく入力してください。',
'content.required' => '本文を正しく入力してください。',
'category_id.required' => 'カテゴリーを選択してください。',
);
$validator = Validator::make($request->all(), $rules, $messages);
if ($validator->passes()) {
$post = new Post;
$post->title = $request->title;
$post->content = $request->content;
$post->category_id = $request->category_id;
$post->save();
return redirect('/posts/create')
->with('message', '投稿が完了しました。');
}else{
return redirect('/posts/create')
->withErrors($validator)
->withInput();
}
}
resources/views/borad配下にcreate.blade.phpというファイルを作成し、以下のようにします。
@extends('layouts.default')
@section('content')
<div class="col-xs-6 col-xs-offset-2">
<h1>投稿ページ</h1>
@if(session('message'))
<div class="bg-info">
<p>{{ session('message') }}</p>
</div>
@endif
@foreach($errors->all() as $message)
<p class="bg-danger">{{ $message }}</p>
@endforeach
<form method="POST" action="/posts">
@csrf
<div class="form-group">
<label for="title" class="">タイトル</label>
<div class="">
<input type="text" class="col-sm-12" name="title">
</div>
</div>
<div class="form-group">
<label for="category_id" class="">カテゴリー</label>
<div class="">
<select name="category_id" type="text" class="">
<option></option>
<option value="1" name="1">カテゴリーその1</option>
<option value="2" name="2">カテゴリーその2</option>
</select>
</div>
</div>
<div class="form-group">
<label for="content" class="">本文</label>
<div class="">
<textarea class="col-sm-12" name="content"></textarea>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">投稿する</button>
</div>
</form>
</div>
@stop
以上で投稿システムが完成しました!コメントシステムなどは割愛させていただきましたが、原理は投稿と同じです。余力のある方はチャレンジしてみてください!
参考
【保存版】Laravelで掲示板を作成する方法【チュートリアル】

WINDII

最新記事 by WINDII (全て見る)
- Canvaが最高すぎる。使い方を完全ガイド【チュートリアルあり】 - 2019年5月14日
- 人気急上昇中のLaravelをはじめよう!【徹底解説】 - 2019年4月23日
- Laravelの認可を理解して実装してみよう! - 2019年3月29日
この記事へのコメントはありません。