掲示板サイトの作成(Laravel)

【はじめに】掲示板の構成
【下準備】プロジェクトの作成、データベースの作成
● bbsプロジェクトを作成します。
データベースを作成します。
mysql --user=root --password=
|
※「Query OK, 1 row affected (0.01 sec)」などと表示されたら成功
ENV編集
データベースの接続情報を.envに設定します。
DB_CONNECTION=mysql
DB_HOST=localhost
DB_DATABASE=bbs_db
DB_USERNAME=root
DB_PASSWORD=
DB_SOCKET=/Applications/MAMP/tmp/mysql/mysql.sock
APP_KEY=base64:xlcHbtqyZfDION8orQrwqm8SibCOBw5fwuEeM7MLfnU=
#### マイグレーション
● 「bbs\database\migrations\」以下にある全てのファイルを削除します。
● 以下コマンドを実行し、マイグレーションファイルを作成します。
$ php artisan make:migration
$ php artisan make:migration
● 作成したマイグレーションファイル2つを以下のように編集します。
class CreatePostsTable extends Migration
{
}
class CreateCommentsTable extends Migration
{
}
● 以下コマンドでマイグレーションを実行し、テーブルを作成します。
$ php artisan migrate
※新たにマイグレーションファイルを追加したときは「php artisan migrate:refresh」を実行します。
【モデルの作成】投稿(Post)、コメント(Comment)
テーブルに対応するモデルを作成します。
● 以下のコマンドを実行し、Post、Comment用のモデルを作成します。
$ php artisan make:model Post
$ php artisan make:model Comment
● 作成したモデルファイル2つを次のように編集します。
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
}
namespace App;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
}
【テストデータ作成】
テストデータ(50件の投稿、各投稿に2つのコメント)を作成します。
● 以下のコマンドを実行し、ファクトリを作成します。
$ php artisan make:factory PostFactory --model=Post
$ php artisan make:factory CommentFactory --model=Comment
作成したファクトリファイル2つを以下のように編集します。
use Faker\Generator as Faker;
$factory->define(App\Post::class, function (Faker $faker) {
return [
];
});
use Faker\Generator as Faker;
$factory->define(App\Post::class, function (Faker $faker) {
return [
];
});
● 「database/seeds/DatabaseSeeder.php」を以下のように編集します。
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run()
{
// PostsTableSeeder(投稿のテストデータ登録)を呼び出して、
//シーディングコマンドで実行されるようにする
$this->call(PostsTableSeeder::class);
}
}
● 以下のコマンドを実行し、テストデータをデータベースに入れます。
$ composer dump-autoload
$ php artisan db:seed
Database seeding completed successfully.
【コントローラー作成】インデックス画面、投稿画面、コメント画面
投稿一覧画面を作成します。
● routes/web.php以下のように編集し、ルーティングを設定します。
// インデックスページ用のルーティング
Route::get('/', 'PostsController@index')->name('top');
// 投稿表示用のルーティング
Route::resource('posts', 'PostsController', ['only' => ['create', 'store', 'show', 'edit', 'update', 'destroy']]);
// コメント投稿用のルーティング
Route::resource('comments', 'CommentsController', ['only' => ['store']]);
※投稿画面のルーティングも設定しています
● 以下のコマンドでコントローラーを作成します。
$ php artisan make:controller PostsController
$ php artisan make:controller CommentsController
● 作成されたコントローラファイルを以下のように編集します。
app/Http/Controllers/PostsController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Post;
class PostsController extends Controller
{
// インデックス用:投稿を作成日時の降順で取得し、posts.indexにデータを渡してビューを生成
public function index()
{
// ページネーションを追加(1ページ10件まで投稿表示)
// 投稿のリストを取得した時に、紐づくコメントを読み込む(取得した投稿数だけコメント数をカウントさせない:n+1問題)
// Laravelではwithメソッドで解決可能
$posts = Post::with(['comments'])->orderBy('created_at', 'desc')->paginate(10);
// コントローラのメソッドでビューを返す
// 第一引数にビューの名前、第二引数にビューに渡したい値(連想配列)を設定
return view('posts.index', compact('posts'));
// compact('posts') は ['posts' => $posts]);と同じ
}
// 投稿画面用:投稿を追加した後は、トップページにリダイレクト
public function create()
{
return view('posts.create');
}
public function store(Request $request)
{
$params = $request->validate([
'title' => 'required|max:50',
'body' => 'required|max:2000',
]);
Post::create($params);
return redirect()->route('top');
}
// 投稿の詳細表示
public function show($post_id)
{
// DBよりURIパラメータと同じIDを持つPostの情報を取得
$post = Post::findOrFail($post_id);
return view('posts.show', [
'post' => $post,
]);
}
// 編集用
public function edit($post_id)
{
// DBよりURIパラメータと同じIDを持つPostの情報を取得
$post = Post::findOrFail($post_id);
return view('posts.edit', [
'post' => $post,
]);
}
// 更新用
public function update($post_id, Request $request)
{
$params = $request->validate([
'title' => 'required|max:50',
'body' => 'required|max:2000',
]);
// DBよりURIパラメータと同じIDを持つPostの情報を取得
$post = Post::findOrFail($post_id);
$post->fill($params)->save();
return redirect()->route('posts.show', ['post' => $post]);
}
// 投稿削除
public function destroy($post_id)
{
// DBよりURIパラメータと同じIDを持つPostの情報を取得
$post = Post::findOrFail($post_id);
\DB::transaction(function () use ($post) {
$post->comments()->delete();
$post->delete();
});
return redirect()->route('top');
}
}
app/Http/Controllers/CommentsController.php
validate([
'post_id' => 'required|exists:posts,id',
'body' => 'required|max:2000',
]);
$post = Post::findOrFail($params['post_id']);
$post->comments()->create($params);
return redirect()->route('posts.show', ['post' => $post]);
}
}
app/Http/Controllers/CommentsController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Post;
class CommentsController extends Controller
{
public function store(Request $request)
{
$params = $request->validate([
'post_id' => 'required|exists:posts,id',
'body' => 'required|max:2000',
]);
$post = Post::findOrFail($params['post_id']);
$post->comments()->create($params);
return redirect()->route('posts.show', ['post' => $post]);
}
}
【ビュー作成】インデックス画面、投稿画面、コメント画面
● layout.blade.phpを次のように編集し、共通テンプレートを作成します。
投稿一覧(resources/views/posts/index.blade.php)
投稿詳細表示(resources/views/posts/show.blade.php)
編集画面(resources/views/posts/edit.blade.php)
【クエリ確認】表示とログファイルに保存
実行されているクエリを確認し、ログファイルに保存します。