本日は、1人のユーザーが複数の投稿をする(1対多)機能を実装します。
投稿機能のER図
ログイン機能を実装した際にusersテーブルは作成されているので、今回はpostsテーブルを作成します。
postsテーブルを作成
新しいテーブルを作成するためにマイグレーションを作成
1、artisanコマンドでマイグレーション作成
[mac] $ php artisan make:migration create_posts_table --create=posts
2、database/migrationsのposts_table.phpに追記し保存
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('post_title');
$table->string('post_content');
$table->integer('user_id');
$table->timestamps();
});
}
3、マイグレーションの実行(テーブルの作成)
[mac] $ php artisan migrate
マイグレーションが成功すると、画像のようにpostsテーブルが追加されます。
モデルを作成
1、artisanコマンドでモデル作成
[mac] $ php artisan make:model Post
2、モデルにリレーションの設定を追加する
App/User.phpに追記します。
// postsテーブルとのリレーション(主テーブル側)
public function posts() { //1対多の「多」側なので複数形
return $this->hasMany('App\Post');
}
App/Post.phpに追記します。
// usersテーブルとのリレーション(従テーブル側)
public function user() { //1対多の「1」側なので単数系
return $this->belongsTo('App\User');
}
投稿画面表示の実装
Postsコントローラーを作成
[mac] $ php artisan make:controller PostsController --resource
Postsコントローラー内にモデル呼び出し&indexメソッドに表示処理を追加
use App\Post;
use App\User;
use Auth;
use Validator;
public function index()
{
// 全ての投稿を取得
$posts = Post::get();
return view('posts',[
'posts'=> $posts
]);
}
Postsコントローラー内のstoreメソッドに登録処理を追加
public function store(Request $request)
{
//バリデーション
$validator = Validator::make($request->all(), [
'post_title' => 'required|max:255',
'post_content' => 'required|max:255',
]);
//バリデーション:エラー
if ($validator->fails()) {
return redirect('/')
->withInput()
->withErrors($validator);
}
//以下に登録処理を記述(Eloquentモデル)
$posts = new Post;
$posts->post_title = $request->post_title;
$posts->post_content = $request->post_content;
$posts->user_id = Auth::id();//ここでログインしているユーザidを登録しています
$posts->save();
return redirect('/');
}
web.phpに投稿ページと投稿処理のルーティングを追加
// 投稿画面の表示
Route::get('/', 'PostsController@index');
// 投稿処理
Route::post('posts', 'PostsController@store');
投稿と一覧表示を実装
/resources/views/posts.blade.phpを作成(投稿フォーム)
@extends('layouts.app')
@section('content')
<div class="card-body">
<div class="card-title">
投稿フォーム
</div>
<!-- バリデーションエラーの表示に使用-->
@include('common.errors')
<!-- 投稿フォーム -->
@if( Auth::check() )
<form action="{{ url('posts') }}" method="POST" class="form-horizontal">
{{ csrf_field() }}
<!-- 投稿のタイトル -->
<div class="form-group">
投稿のタイトル
<div class="col-sm-6">
<input type="text" name="post_title" class="form-control">
</div>
</div>
<!-- 投稿の本文 -->
<div class="form-group">
投稿の本文
<div class="col-sm-6">
<input type="text" name="post_content" class="form-control">
</div>
</div>
<!-- 登録ボタン -->
<div class="form-group">
<div class="col-sm-offset-3 col-sm-6">
<button type="submit" class="btn btn-primary">
Save
</button>
</div>
</div>
</form>
@endif
</div>
<!-- 全ての投稿リスト -->
@if (count($posts) > 0)
<div class="card-body">
<div class="card-body">
<table class="table table-striped task-table">
<!-- テーブルヘッダ -->
<thead>
<th>投稿一覧</th>
<th> </th>
</thead>
<!-- テーブル本体 -->
<tbody>
@foreach ($posts as $post)
<tr>
<!-- 投稿タイトル -->
<td class="table-text">
<div>{{ $post->post_title }}</div>
</td>
<!-- 投稿詳細 -->
<td class="table-text">
<div>{{ $post->post_content }}</div>
</td>
<!-- 投稿者名の表示 -->
<td class="table-text">
<div>{{ $post->user->name }}</div>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endif
@endsection
エラー表示の作成
/resources/views/common/errors.blade.phpを作成
@if (count($errors) > 0)
<!-- Form Error List -->
<div class="alert alert-danger">
<div><strong>入力した文字を修正してください。</strong></div>
<div>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
</div>
@endif
投稿機能の実装完了
ログインしてないときの表示(投稿フォーム非表示)
ログイン時の表示(投稿フォーム表示)