ホーム > Laravel > Laravelでカテゴリー機能を実装する方法
Laravel

Laravelでカテゴリー機能を実装する方法

いつもご利用ありがとうございます。
この記事には広告が掲載されており、その広告費によって運営しています。

関連動画

質問やフィードバック

この記事や動画に関する質問やフィードバックあれば、動画のコメント欄にてお気軽にコメントしてください。

⇨ Laravel 記事の目次はこちら

Laravel でポストにカテゴリー機能を実装する方法についてまとめました

今回やること

タイトルと内容だけを投稿する簡単な機能がすでにあるところから、カテゴリーを選択して投稿し、そのカテゴリーを表示するところまで、今回実装していきます。

流れ

  1. posts テーブルに category_id カラムを追加する
  2. categories テーブルを作り、カテゴリーを用意する
  3. データで用意したカテゴリーを元に保存ページを作る
  4. 保存時に category_id を保存する
  5. リレーションを使って表示

投稿する機能が分からない人はこちらの記事をご覧ください。

【初心者向け】Laravel で投稿機能を作る方法(掲示板的なやつ)

posts テーブルに category_id カラムを追加する

コマンドを打ち、カラムを追加するマイグレーションファイルを新規作成します。

php artisan make:migration add_category_id_to_posts_table

そうすると新しいファイルが、database/migrations/に生成されるのでそれを開きます。

開いたら、以下のように up()と down()の関数をこのようにしてください。

public function up(): void
    {
        Schema::table('posts', function (Blueprint $table) {
            $table->integer('category_id')
                ->after('title') //titleというカラムがない人はこの行をコメントアウトまたは変更
                ->nullable();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::table('posts', function (Blueprint $table) {
            $table->dropColumn('category_id');
        });
    }

このように書いたら、コマンドで実行するとカラムが追加されます。

php artisan migrate

その他の方法

本番環境で運用していない場合、posts テーブルのマイグレーションファイルに

$table->integer('category_id')->nullable();

を追記して、以下のコマンドでリセットしても大丈夫です。

ファイルが増えすぎると大変なので開発環境で仕様を追加する場合は、むしろこっちの方が良いと思います。

php artisan migrate:fresh --seed

コマンドで反映します。

categories テーブルを作り、カテゴリーを用意する

カテゴリーテーブルを作る

コマンドでマイグレーションファイルを作成し、カテゴリー用のテーブルを作成します。

php artisan make:migration create_categories_table

先ほどと同様に、database/migrations/にファイルが生成されるのでそれを開きます。

そのファイルには、

public function up(): void
{
    Schema::create('categories', function (Blueprint $table) {
        $table->id();
        $table->string('name'); //追加
        $table->timestamps();
    });
}

と書き、nameというカラムを追加します。コマンドを実行し、データベースに反映させます。

php artisan migrate
php artisan make:model Category

これで、categoriesテーブルができます。ついでにモデルも作成しておきました。

カテゴリーのデータを作る

コマンドでシーダーファイルを作成し、シーダーファイルでカテゴリーを作ります。

php artisan make:seeder CategoriesTableSeeder

今作成された、database/seeder/CategoriesTableSeeder.phpを編集します。


use App\Models\Category;

~~~~~

public function run(): void
{
    $categories = ['カテゴリー1','カテゴリー2','カテゴリー3'];
    foreach($categories as $category){
        $c = new Category;
        $c->name = $category;
        $c->save();
    }
}

database/seeders/DatabaseSeeder.phpに追記します。

public function run(): void
{
    // User::factory(10)->create();
    $this->call([
        CategoriesTableSeeder::class, //追記
    ]);
    // User::factory()->create([
    //     'name' => 'Test User',
    //     'email' => 'test@example.com',
    // ]);
}

シーダーを実行します。

php artisan db:seed
または
php artisan migrate:fresh --seed

データで用意したカテゴリーを元に、保存ページを作る

create ページのコントローラーを開き、データを View に送ります。

app/Http/Controller/PostController.php

use App\Models\Category;
~~~
    public function create()
    {
        $categories = Category::all();
        return view('post/create',compact('categories'));
    }

views/post/create.blade.phpに以下のように追記し、セレクトを今のデータを元に作成します。

<form method="POST" action="{{ route('post.store') }}">
  @csrf
  <div>
    <input name="title" />
  </div>
  <!-- 追記 -->
  <div>
    <select name="categoryId">
      @foreach($categories as $category)
      <option value="{{ $category->id }}">{{ $category->name }}</option>
      @endforeach
    </select>
  </div>
  <!-- 追記ここまで -->
  <div>
    <textarea name="content"></textarea>
  </div>
  <button>送信</button>
</form>

保存時に category_id を保存する

さきほどセレクトでデータを送信することができるようになったので、あとはコントローラーの保存の場所を変更し、カテゴリーの ID を保存するようにします。

    public function store(Request $request)
    {
        $title = $request->title;
        $content = $request->content;
        $categoryId = $request->categoryId; //追記

        $post = new Post;
        $post->user_id = Auth::id();
        $post->title = $title;
        $post->category_id = $categoryId; //追記
        $post->content = $content;
        $post->save();

        return redirect('/');
    }

リレーションを使って表示

リレーションを書く

ポストモデルにリレーションを書き、カテゴリーを関連づけます。

app/Models/Post.phpを変更

class Post extends Model
{
    //略
    public function category() //追加
    {
        return $this->belongsTo(Category::class);
    }
}

一覧ページのコントローラーを変更

app/Http/Controllers/HomeController.php

use App\Models\Post;
~~~
    function index()
    {
        $posts = Post::with('user')
            ->with('category') //追加
            ->orderBy('id','desc')
            ->take(10)
            ->get();

        return view('welcome',compact('posts'));
    }

with()を使って、Eager Load をしっかり使っていきましょう。

一覧ページの View を変更

リレーションを表示したい時はこのように、メソッドチェーンで書いてあげれば OK です。

@foreach($posts as $post)
<!-- 略 -->
<p>{{ $post->category->name }}</p>
<!-- 略 -->
@endforeach

以上で、カテゴリーの保存と表示を実装しました。

テキストでは良く分からなかった部分があったら動画をごらんくださいませ。

誰かの参考になれば幸いでございます。

フィードバックのお願い
この記事のフィードバックがありましたらYoutubeの適当な動画にコメントしていただいたり、お問い合わせからご連絡ください。