見出し画像

[laravel8]カテゴリーのブログ記事を表示

前回はブログにカテゴリーを追加しました。

今回はそのカテゴリーごとのブログ記事を表示できるようにしたいと思います。

Eloquent Relationship

前回Postモデルに

app/Models/Post.php

    public function category()
   {
       return $this->belongsTo(Category::class);
   }

Categoryメソッドを追加し、

$post->category

と記事のカテゴリーを取得できるようEloquent Relationshipを定義しました。

今回は逆にカテゴリーから記事を取得できるようにEloquent Relationshipを定義します。

app/Models/Category.php

    public function posts()
   {
       return $this->hasMany(Post::class);
   }

記事からカテゴリを取得するときは、記事が属している(belongsTo)カテゴリーだったのでbelongsToを使用しました。

しかしカテゴリーが記事に属しているわけではないので今回は違ってきます。カテゴリーは複数の記事を持つことができるので、この場合はhasMany Relationship を使います。

これで $category->postsでそのカテゴリーに属する記事すべてを取得することができます。

Tinkerで試してみます。

$php artisan tinker
Psy Shell v0.10.8 (PHP 8.0.3 — cli) by Justin Hileman
>>> App\Models\Category::first()->posts;
=> Illuminate\Database\Eloquent\Collection {#4226
    all: [
      App\Models\Post {#4070
        id: 1,
        category_id: 1,
        slug: "my-family-post",
        title: "My Family Post",
        excerpt: "Excerpt for my family post",
        body: "body for my family post",
        created_at: "2021-05-25 11:17:49",
        updated_at: "2021-05-25 11:17:49",
        published_at: null,
      },
    ],
  }
>>>

App\Models\Category::first() でカテゴリを取得し、その記事を

App\Models\Category::first()->posts;

で取得することができました。

ルーティング

ルーティングのファイルは今までと同じようにweb.phpなので、ここに新しくcategoryのためのルーティングを追加します。

routes/web.php

Route::get('/categories/{category:slug}', function (Category $category){
   return view('posts', [
       'posts' => $category->posts
   ]);
});

ルート・モデル・バインディングを使うので

ワイルドカードのcategoryとコールバックのパラメータの変数名をcategoryを同じにし、さらにcategoriesテーブルのslugをURLで使用するために

{category:slug}

と明示します。

View

ブログ記事一覧のview

resources/views/posts.blade.php

<x-layout>
   @foreach($posts as $post)
       <article>
           <h1>
               <a href="/posts/{{ $post->slug}}" >
                   {{ $post->title }}
               </a>
           </h1>

           <p>
               <a href="/categories/{{$post->category->slug}}">{{ $post->category->name }}</a>
           </p>

           <div>
               {{ $post->excerpt }}
           </div>
       </article>
   @endforeach
</x-layout>

hrefに 

"/categories/{{$post->category->slug}}"

としてURLにカテゴリーのslugを適用しています。

Topページ

スクリーンショット 2021-05-27 20.18.51

からカテゴリーのWorkをクリックすると

http://localhost:8000/categories/work

スクリーンショット 2021-05-27 20.20.28

一つしか記事がないですが、Workカテゴリーの記事が表示されています。

ソースコード

今回のソースコードは次になります。


この記事が気に入ったらサポートをしてみませんか?