🦁
多対多のリレーションをLaravel-Adminで扱う(表示・更新・作成)
例えば「記事」に対して複数の登録済みの「カテゴリ」が紐づく、のように多対多のリレーションを貼ることは結構あるかと思います。
その場合Laravel-Adminの管理画面の方でもこの記事に何のタグが紐づいているのか?を表示したいですよね。
今回はLaravel-Adminで多対多のリレーションの項目の表示・編集・作成の方法についてお話します。
この記事ではarticlesとcategoriesを例にします
artilcesテーブルとcategoriesテーブルが多対多の関係になっているとします。
articles
- id
- title
- content
- posted_at
categories
- id
- name
article_category(中間テーブル)
- article_id
- category_id
準備編
Admin用のArticleControllerを作成する(準備)
php artisan admin:make ArticleController
モデルに追記する
Article.phpで、カテゴリーとのリレーションを作成します。
public function categories()
{
return $this->belongsToMany(Category::class, 'article_category')->using(ArticleCategory::class);
}
僕はpivotを使用して多対多のリレーションを行うことが多いです。
ArticleCategoryのモデルはこのようになっています。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\Pivot;
class ArticleCategory extends Pivot
{
use HasFactory;
protected $guarded = [];
}
grid, detail, formメソッドを編集する(本実装)
gridで一覧表示ページに記事に紐づくカテゴリを表示する
Laravel-Adminでは grid
に一覧表示する項目、 detail
に個別表示する項目 form
に作成・編集する項目を記入します。
多対多のリレーションではそれぞれこのように記述します。
ArticleController.php
protected function grid()
{
$grid = new Grid(new Article());
$grid->column('id', __('Id'));
$grid->column('title', 'タイトル');
$grid->column('content', '本文');
$grid->categories()->display(function ($categories) {
$categories = array_map(function ($category) {
return "<span class='label label-success'>{$category['name']} </span>";
}, $categories);
return join(' ', $categories);
});
}
リレーション先のカテゴリをarray_mapを使って全部のカテゴリを表示しています。
detailで個別表示ページに記事に紐づくカテゴリを表示する
protected function detail($id)
{
$article = Article::findOrFail($id);
$show = new Show($article);
$show->field('id', __('Id'));
$show->field('title', 'タイトル');
$show->field('content', '本文');
$show->categories('カテゴリ', function ($category) {
$category->setResource('/admin/categories');
$category->name();
});
}
これを実現するためには、事前に categories
の一覧ページを管理画面側で作っておく必要があります。URLはご自身のものに合わせてください。
formで編集・作成ページでカテゴリを選択できるようにする
protected function form()
{
$form = new Form(new Article());
$form->text('title', 'タイトル');
$form->text('content', '本文');
$form->multipleSelect('categories', 'カテゴリ')->options(Category::all()->pluck('name', 'id'));
return $form;
}
全てのカテゴリのidとnameを配列で引っ張ってきて、それを複数選択セレクトボックスに表示しています。
これで記事に紐づくカテゴリを選択することができます。
終わりに
Laravel-Adminって結構有名だと思うのですが、意外と情報がありません。
試行錯誤しながら、メモとして記事に残していきたいなと思います。
Discussion