Laravelでカテゴリー機能を実装する方法
いつもご利用ありがとうございます。
この記事には広告が掲載されており、その広告費によって運営しています。
目次
関連動画
質問やフィードバック
この記事や動画に関する質問やフィードバックあれば、動画のコメント欄にてお気軽にコメントしてください。
Laravel でポストにカテゴリー機能を実装する方法についてまとめました
今回やること
タイトルと内容だけを投稿する簡単な機能がすでにあるところから、カテゴリーを選択して投稿し、そのカテゴリーを表示するところまで、今回実装していきます。
流れ
- posts テーブルに category_id カラムを追加する
- categories テーブルを作り、カテゴリーを用意する
- データで用意したカテゴリーを元に保存ページを作る
- 保存時に category_id を保存する
- リレーションを使って表示
投稿する機能が分からない人はこちらの記事をご覧ください。
【初心者向け】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
以上で、カテゴリーの保存と表示を実装しました。
テキストでは良く分からなかった部分があったら動画をごらんくださいませ。
誰かの参考になれば幸いでございます。