#【 Laravel 6 】投稿者ごとの投稿記事を取得し一覧を表示する
2019年11月から、Laravel歴数ヶ月の初心者が投稿型ナレッジベースのコミュニティサイトを作るというチャレンジ中。作りたいアプリケーション→機能を因数分解→ググる→先人の轍をたどる(写経する)→ぬかるみにはまる→エラー解消の神を探す→解決を繰り返す日々( ·ㅂ·)و 。備忘録として、Qiitaに投稿しています。
今回は、それぞれの投稿者の投稿記事を一覧で表示させる機能を実装していきます。
##前提
全ての投稿の一覧を表示するindex.blade.phpは、【 Laravel 6 】投稿の表示・修正・更新・削除)で、すでにできている前提です。
##投稿者の名前にリンクを貼る
<div>
投稿者: <a href="{{ route('users.show', $post->user_id)}}">{{ $post->name }}</a>
</div>
##リレーションを設定
投稿者は複数の投稿をもち、投稿は一つの投稿者に従属する関係性を、hasManyメソッドとbelongsToメソッドを使って設定していきます。それぞれのモデルのclassに以下を追加します。
注意するポイントとしては、functionの後の、postsは複数形、userは単数での表記になっている点です。英語表現に置き換えれば、当然(posts belong to one user / one user has many posts)かもしれませんが、片方が複数、片方が単数として書かなければならないことに気づくのには少々時間がかかってしまいました。
# User.php
// リレーションの設定。投稿者は複数の投稿を持つ。
public function posts()
{
return $this->hasMany('App\Post');
}
# Post.php
// リレーションの設定。投稿は一つの投稿者に従属する。
public function user()
{
return $this->belongsTo('App\User');
}
##ルーティング
投稿者のリンクを押した時、投稿者の書いた投稿の一覧へ飛ぶようにルーティングを設定します。
// ユーザー投稿の一覧表示画面
Route::resource('/users', 'UsersController', ['only' => ['show']]);
下記のコマンドを叩いて、Usersコントローラーを作成します。
$ php artisan make:controller UsersController --resource
Usersコントローラーに下記を追加します。
public function show(User $user)
{
$user = User::find($user->id); //idが、リクエストされた$userのidと一致するuserを取得
$posts = Post::where('user_id', $user->id) //$userによる投稿を取得
->orderBy('created_at', 'desc') // 投稿作成日が新しい順に並べる
->paginate(10); // ページネーション;
return view('users.show', [
'user_name' => $user->name, // $user名をviewへ渡す
'posts' => $posts, // $userの書いた記事をviewへ渡す
]);
}
##Viewファイルで一覧表示
/resources/views/配下にusersフォルダを作成、その中にshow.blade.phpを作り、以下のように、$user_nameによる投稿の一覧を表示してあげましょう。
@extends('layouts.app')
@section('content')
<div class="container mt-4">
<div class="mb-4">
<p>{{ $user_name }}の投稿一覧</p>
</div>
@foreach ($posts as $post)
<div class="card mb-4">
<div class="card-header">
タイトル: {{ $post->title }}
投稿者: <a href="{{ route('users.show', $post->user_id) }}">{{ $user_name }}</a>
</div>
<div class="card-body">
<p class="card-text">
<li> {{ \Illuminate\Support\Str::limit($post->body, 140) }}
</p>
<a class="card-link" href="{{ route('posts.show', ['post' => $post]) }}">
続きを読む
</a>
<p class="card-text">
@foreach ($post->tags as $tag)
<a href="{{route('top', ['tag_id'=>$tag->id])}}">
{{ $tag->name }}
</a>
@endforeach
</p>
</div>
<div class="card-footer">
<span class="mr-2">
投稿日時 {{ $post->created_at->format('Y.m.d') }}
</span>
@if ($post->comments->count())
<span class="badge badge-primary">
コメント {{ $post->comments->count() }}件
</span>
@endif
</div>
</div>
@endforeach
{{-- ページネーション --}}
<div class="d-flex justify-content-center mb-5">
{{ $posts->links() }}
</div>
</div>
@endsection
以上です。