🦁

多対多のリレーションをLaravel-Adminで扱う(表示・更新・作成)

2021/09/13に公開

例えば「記事」に対して複数の登録済みの「カテゴリ」が紐づく、のように多対多のリレーションを貼ることは結構あるかと思います。

その場合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('&nbsp;', $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