• トップ
  • ブログ一覧
  • LaravelとFilamentを使って管理画面を爆速構築
  • LaravelとFilamentを使って管理画面を爆速構築

    モリ(エンジニア)モリ(エンジニア)
    2024.06.18

    IT技術

    こんにちは!

    Laravelを使ったアプリを作る際に管理画面が必要になったのですが、Filamentというライブラリを使うと爆速でいい感じの管理画面を作ることができました!

    今回はFilamentについて、簡単なブログ投稿機能を作りながら紹介していきたいと思います!

    環境

    • Mac M1
    • Laravel 11

    ※事前に下記を対応している状態です。

    • Laravel公式サイトのこちらからDockerを使ってLaravelのプロジェクトを立ち上げている
    • こちらの内容の通りaliasの設定をしてsailコマンドを簡単に使えるようにしている

     

    Filamentの導入

    既存のLaravelプロジェクト直下で次のコマンドを使ってFilamentを導入していきます。

    1$ sail composer require filament/filament:"^3.2" -W
    2$ sail php artisan filament:install --panels

    次のように聞かれるので、2回ともデフォルトのままEnterキーを押します。

    1What is the ID? ─────────────────────────────────────────────┐
    2 │ admin                                                        │
    3 └──────────────────────────────────────────────────────────────┘
    4
    5All done! Would you like to show some love by starring the Filament repo on GitHub?6│ ● Yes /No7└─────────────────────────────────────────────────────────────────────────────────────┘

    完了後に localhost/adminにアクセスすると、すでにログイン画面が完成しておりました。

    ログインユーザーの作成

    ではログインするためのユーザーを作成するために次のコマンドを実行します。

    1$sail php artisan make:filament-user

    すると下記のように「Name」と「Email address」と「Password」の入力を求められるので、設定してください。

    1$ sail php artisan make:filament-user
    2
    3
    4
    5Name ────────────────────────────────────────────────────────┐
    6 │ test                                                         │
    7 └──────────────────────────────────────────────────────────────┘
    8
    9Email address ───────────────────────────────────────────────┐
    10 │ test@demo.com11 └──────────────────────────────────────────────────────────────┘
    12
    13Password ────────────────────────────────────────────────────┐
    14 │ ••••••••                                                     │
    15 └──────────────────────────────────────────────────────────────┘
    16
    17   INFO  Success! test@demo.com may now log in at http://localhost/admin/login.

    では、上記で設定したメールアドレスとパスワードを使って、ログインしてみましょう!

    ログインに成功すると、下の画像のような画面になるかと思います!

    モデルの追加とデータベースのセットアップ

    先述した通り、簡単なブログ投稿機能を作っていくので、「投稿」と「カテゴリー」のモデルを次のコマンドを実行して追加します。

    1$sail php artisan make:model Post -m
    2$sail php artisan make:model Category -m

    app/ModelsディレクトリにPost.phpファイルとCategory.phpファイル、databases/migrationsディレクトリにそれぞれのマイグレーションファイルが作成されます。

    続いて、次のようにマイグレーションファイルを編集してテーブルの列を追加します。

    1// YYYY_MM_DD_XXXXX_create_posts_table.php
    2.
    3.
    4    public function up(): void
    5    {
    6        Schema::create('posts', function (Blueprint $table) {
    7            $table->id();
    8            $table->string('title');                                                     // 追加部分
    9            $table->text('content');                                                     // 追加部分
    10            $table->foreignId('user_id')->constrained('users')->cascadeOnDelete();  // 追加部分
    11            $table->foreignId('category_id')->constrained('categories');               // 追加部分
    12            $table->timestamps();
    13        });
    14    }
    15.
    16.
    1// YYYY_MM_DD_XXXXX_create_categories_table.php
    2.
    3.
    4    public function up(): void
    5    {
    6        Schema::create('categories', function (Blueprint $table) {
    7            $table->id();
    8            $table->string("name");  // 追加部分
    9            $table->timestamps();
    10        });
    11    }
    12.
    13.

    上記のコードを追加したら、次のコマンドでpostsテーブルとcategoriesテーブルを作成します。

    ※postsテーブルにcategoriesテーブルのidが外部キーとして設定されているため、先にcategoriesテーブルを作成する必要があります。

    1$ sail php artisan migrate --path=/database/migrations/YYYY_MM_DD_XXXXX_create_categories_table.php
    2$ sail php artisan migrate --path=/database/migrations/YYYY_MM_DD_XXXXX_create_posts_table.php

    続いて、Laravelのセキュリティ機能の1つの一括割り当て保護(Mass Assignment Protection)を全てのモデルから解除します。(今回は説明を簡潔にするため解除しますが、本番運用のアプリケーションで使用する際は適切に設定してあげてください。)

    そのために、次のコードをapp/Providers/AppServiceProvider.php の boot() メソッドに追加します。

    1// app/Providers/AppServiceProvider.php
    2    public function boot(): void
    3    {
    4        Model::unguard();
    5    }

    最後にモデル間のリレーションを設定します。
    次のようにapp/Models/の中のUser.php、Post.php、Category.phpにコードを追加します。

    1// app/Models/User.php
    2.
    3.
    4use Illuminate\Database\Eloquent\Relations\HasMany;
    5.
    6.
    7    public function posts(): HasMany
    8    {
    9        return $this->hasMany(Post::class);
    10    }
    11.
    12.
    1// app/Models/Post.php
    2use Illuminate\Database\Eloquent\Factories\HasFactory;
    3use Illuminate\Database\Eloquent\Model;
    4use Illuminate\Database\Eloquent\Relations\BelongsTo;
    5
    6class Post extends Model
    7{
    8    use HasFactory;
    9
    10    public function user(): BelongsTo
    11    {
    12        return $this->belongsTo(User::class);
    13    }
    14
    15    public function category(): BelongsTo
    16    {
    17        return $this->belongsTo(Category::class);
    18    }
    19}
    1// app/Models/Category.php
    2use Illuminate\Database\Eloquent\Factories\HasFactory;
    3use Illuminate\Database\Eloquent\Model;
    4use Illuminate\Database\Eloquent\Relations\HasMany;
    5
    6class Category extends Model
    7{
    8    use HasFactory;
    9
    10    public function posts(): HasMany
    11    {
    12        return $this->hasMany(Post::class);
    13    }
    14}

     

    リソースの作成

    FilamentのリソースとはCRUDの処理を操作するインターフェイスを構築するために使用される静的クラスことです。

    次のコマンドでCategoryモデルとPostモデルのリソースを作成します。

    1$ sail php artisan make:filament-resource Category
    2$ sail php artisan make:filament-resource Post

    上記コマンド実行後、app/Filament/Resourcesディレクトリを見ると下の画像のように、CategoryリソースとPostリソースのいくつかのファイルが作成されます。

    ダッシュボードの画面をリロードすると下の画像のように「Categories」と「Posts」のリンクが左側のメニューに追加されます。

    Categoriesのリンクをクリックすると下の画像のような画面に遷移します。

    カテゴリーの登録をしていないので、「No categories」という表示がされます。

     

    フォームの作成

    では、カテゴリーを登録できるように実装していきます。

    app/Filament/ResourcesディレクトリにあるCategoryResource.phpを次のように修正します。

    1// app/Filament/Resources/CategoryResource.php
    2.
    3.
    4    public static function form(Form $form): Form
    5    {
    6        return $form
    7            ->schema([
    8                Forms\Components\TextInput::make('name')  // 修正部分
    9                    ->required()                          // 修正部分
    10                    ->maxLength(255)                      // 修正部分
    11            ]);
    12    }
    13.
    14.

    Categories画面の右上にある「New category」ボタンを押すと、下の画像のように、カテゴリー名の入力欄が追加されます。

    ここで、Nameの入力欄に「PHP」と入力してカテゴリーを登録してみます。

    しかし、Categories画面をみても「PHP」の表示がありません。

    登録したデータを表示できるようにしていきます。

    テーブルの作成

    app/Filament/ResourcesディレクトリにあるCategoryResource.phpを次のように修正します。

    1// app/Filament/Resources/CategoryResource.php
    2.
    3.
    4    public static function table(Table $table): Table
    5    {
    6        return $table
    7            ->columns([
    8                Tables\Columns\TextColumn::make('name')  // 修正部分
    9            ])
    10.
    11.

    Categories画面をリロードすると下の画像のようにCategoryのnameが表示されるようになります。

    では下の画像のように別のカテゴリーも登録してみます。

    「Java」と「MySQL」というカテゴリーを追加してみました。

    では、このような管理画面でよくある機能の「検索機能」と「ソート機能」を実装していきたいと思います。

    CategoryResource.phpを次のようにコードを追加します。

    1// app/Filament/Resources/CategoryResource.php
    2.
    3.
    4    public static function table(Table $table): Table
    5    {
    6        return $table
    7            ->columns([
    8                Tables\Columns\TextColumn::make('name')
    9                    ->searchable()  // 追加部分
    10                    ->sortable(),   // 追加部分
    11            ])
    12.
    13.

    画面をリロードすると下の画像のように、右上に検索ボックスとNameの右横に矢印が追加されるのがわかります。

     

    Postのフォームとテーブルを作成

    では、PostでもCategoryと同じようにフォームとテーブルを作成します。

    コードを次のように変更します。

    1// app/Filament/Resources/PostResource.php
    2.
    3.
    4    public static function form(Form $form): Form
    5    {
    6        return $form
    7            ->schema([
    8                Forms\Components\TextInput::make('title')
    9                    ->required()
    10                    ->maxLength(255),
    11                Forms\Components\Select::make('user_id')
    12                    ->relationship(name: 'user', titleAttribute: 'name'),
    13                Forms\Components\Select::make('category_id')
    14                    ->relationship(name: 'category', titleAttribute: 'name'),
    15                Forms\Components\RichEditor::make('content')
    16                    ->columnSpanFull(),
    17
    18            ]);
    19    }
    20
    21    public static function table(Table $table): Table
    22    {
    23        return $table
    24            ->columns([
    25                Tables\Columns\TextColumn::make('title')
    26                    ->searchable()
    27                    ->sortable(),
    28                Tables\Columns\TextColumn::make('user.name')
    29                    ->searchable()
    30                    ->sortable(),
    31                Tables\Columns\TextColumn::make('category.name')
    32                    ->searchable()
    33                    ->sortable(),
    34            ])
    35    }
    36.
    37.

    上記コードで新しく出てきてコードを簡単に説明します。

    relationship(name: 'user', titleAttribute: 'name')

    relationship()メソッドは、ModelでBelongsToの関係を設定した値を自動的にformのoption要素として取得することができます。name引数はモデル内の関係を定義するもの、titleAttribute引数は関連するテーブルから使用する列名です。(上記の場合、Userモデルのnameカラムの値をoption要素に取得してくることになります)

     

    Filament\Forms\Components\RichEditor

    HTMLのコンテンツを編集およびプレビューしたり、画像をアップロードしたりできるフィールドを作れます。

     

    columnSpanFull()

    設定したフィールドをの幅を親要素の幅まで広げるメソッドです。

     

    上記コードの修正を行ったら画面をリロードして、投稿を作ってみます。

    Postsの一覧画面からNew postボタンをクリックすると下の画像のような画面になります。

    下の画像のように「Javaの勉強法」という仮のPostを作ってみました。(※文章はChatGPTに適当に出してもらったものです)

    これで簡易的なブログ投稿ができる管理画面が完成です。

     

    おわりに

    簡易的ではあるものの、想像以上のスピードでいい感じの管理画面が作れて驚きました。

    公式のドキュメントがかなり充実していそうなので(全部は見切れていない)機会があれば他の機能も試したいと思います!

     

    参照URL

    https://filamentphp.com/docs/3.x/infolists/installation

    ライトコードでは、エンジニアを積極採用中!

    ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。

    採用情報へ

    モリ(エンジニア)
    モリ(エンジニア)
    Show more...

    おすすめ記事

    エンジニア大募集中!

    ライトコードでは、エンジニアを積極採用中です。

    特に、WEBエンジニアとモバイルエンジニアは是非ご応募お待ちしております!

    また、フリーランスエンジニア様も大募集中です。

    background