2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Laravel12でFormello触ってみた

Last updated at Posted at 2025-08-24

はじめに

  • Laravelで、フォーム作成を効率化するパッケージ「Formello」がリリースされたので、簡単に触っていく

前提

  • Laravel9以上(Laravel12/PHP8.3で検証)
  • docker環境

内容

docker環境

スクリーンショット 2025-08-24 14.34.31.png

ライブラリインストール

composer require metalogico/laravel-formello

スクリーンショット 2025-08-24 14.39.52.png

  • アセットの公開設定
php artisan vendor:publish --tag=formello-assets
  • 更新時にアセットを自動公開するように設定
src/composer.json
    "scripts": {
        "post-update-cmd": [
            "@php artisan vendor:publish --tag=formello-assets --force"
        ]
    }

Modelを作成する

  • フォーム作成したいのでProductモデルを作成する
php artisan make:model Product -m
src/database/migrations/2025_08_24_055039_create_products_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('products', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->text('description')->nullable();
            $table->boolean('in_stock')->default(true);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('products');
    }
};

Formを作成する

  • App/Forms配下に作成される
php artisan make:formello --model=Product
<?php

namespace App\Forms;

use Metalogico\Formello\Formello;

class ProductForm extends Formello
{
    protected function create(): array
    {
        return [
            'method' => 'POST',
            'action' => route('products.store'),
        ];
    }

    protected function edit(): array
    {
        return [
            'method' => 'PATCH',
            'action' => route('products.update', $this->model->id),
        ];
    }    

    protected function fields(): array
    {
        return [

        ];
    }
}
  • fieldsに追記する
    protected function fields(): array
    {
        return [
            'name' => [
                'label' => __('商品名'),
                'help' => 'Enter the name of the product',
            ],
            'description' => [
                'label' => __('説明'),
            ],
            'in_stock' => [
                'label' => __('ストック'),
            ],
        ];
    }

  • フィールドをモデルの$fillable配列に追加する
src/app/Models/Product.php
class Product extends Model
{
    protected $fillable = [
        'name',
        'description',
        'in_stock',
    ];
}

Controller作る

php artisan make:controller ProductController
src/app/Http/Controllers/ProductController.php
<?php

namespace App\Http\Controllers;

use App\Forms\ProductForm;
use App\Models\Product;

class ProductController extends Controller
{
    public function create()
    {
        $formello = new ProductForm(Product::class);
        return view('products.create', [
            'formello' => $formello
        ]);
    }

    public function edit(Product $product)
    {
        $formello = new ProductForm($product);
        return view('products.edit', [
            'formello' => $formello
        ]);
    }
}

viewを作成する

src/resources/views/layouts/app.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>@yield('title', 'My App')</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
    @formelloStyles
</head>
<body>
<div class="container mt-4">
    @yield('content')
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
@formelloScripts
</body>
</html>

src/resources/views/products/create.blade.php
@extends('layouts.app')

@section('content')
    <div class="container">
        <h1>商品登録フォーム</h1>
        {!! $formello->render() !!}
    </div>
@endsection

route作成

Route::get('/products/create', [ProductController::class, 'create'])->name('products.create');
  • route作成して、以下アクセスするとFormが作成されている!便利だな。

スクリーンショット 2025-08-24 15.38.05.png

  • フォームの各フィールドだけを描画したい場合はこうするといいみたい
src/resources/views/products/create.blade.php
@extends('layouts.app')

@section('content')
    <div class="container">
        <h1>商品登録フォーム</h1>
        @foreach ($formello->getFields() as $name => $field)
            {!! $formello->renderField($name) !!}
        @endforeach
    </div>
@endsection

スクリーンショット 2025-08-24 15.40.44.png

Formのタイプを変えてみる

  • 説明をテキストエリア・ストックをチェックボックスへ変更してみる

  • checkboxesは、choicesを設定しないとエラーになるので注意

src/app/Forms/ProductForm.php
()
    protected function fields(): array
    {
        return [
            'name' => [
                'label' => __('商品名'),
                'help' => 'Enter the name of the product',
            ],
            'description' => [
                'label' => __('説明'),
                'widget' => 'textarea',
            ],
            'in_stock' => [
                'label' => __('ストック'),
                'widget' => 'checkboxes',
                'choices' => [
                    'a' => 'オプションA',
                    'b' => 'オプションB',
                    'c' => 'オプションC',
                ],
            ],
        ];
    }

スクリーンショット 2025-08-24 15.48.14.png

  • ストックをセレクトへ変更してみる
            'in_stock' => [
                'label' => __('ストック'),
                'widget' => 'select',
                'choices' => [
                    'yes' => '在庫あり',
                    'no'  => '在庫なし',
                    'soon' => '入荷予定',
                ],
            ],

スクリーンショット 2025-08-24 15.51.54.png

まとめ

最低限のフォームが簡単にできて、render()で全体、renderField()で部分描画できるのも便利なライブラリだな〜って思いました。
requiredで必須チェックの機能はあるみたいだけど、ビジネスロジックを書きたい場合はFormRequestで定義する必要がありそう。
フォームをPHPクラスで宣言して、自動でレンダリングできる点はSymfonyのFormTypeに似ているなって感じました。(今サクッと触った印象では。)

参考記事・リンク

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?