mermaid.jsをrecca0120/laravel-erdでlaravelから生成する

2025/03/12に公開

https://packagist.org/packages/recca0120/laravel-erd

以下のようなmigrationがあった場合のER図を作る

    public function up(): void
    {
        Schema::create('tasks', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')->constrained()->onDelete('cascade');
            $table->string('title');
            $table->text('description')->nullable();
            $table->boolean('is_completed')->default(false);
            $table->date('due_date')->nullable();
            $table->timestamps();
        });
    }

インストール

composer require recca0120/laravel-erd

php artisan erd:generate

実行結果

http://server/laravel-erd とかのpathでいきなり見えるようになっている。これは

vendor/recca0120/laravel-erd/routes/web.php
<?php

use Illuminate\Support\Facades\Route;
use Recca0120\LaravelErd\Http\Controllers\LaravelErdController;

Route::get(config('laravel-erd.uri').'/{file?}', [LaravelErdController::class, 'index'])
    ->name('laravel-erd.show')
    ->middleware(config('laravel-erd.middleware'))
    ->where('file', '.*');

で行っているが、pathが気にいらなくても当然、vendorの下を直接触ってはいけない

config

vendor/recca0120/laravel-erd/config/laravel-erd.php
<?php

return [
    'uri' => env('LARAVEL_ERD_URI', 'laravel-erd'),
    'storage_path' => storage_path('framework/cache/laravel-erd'),
    'extension' => env('LARAVEL_ERD_EXTENSION', 'sql'),
    'middleware' => [],
    'binary' => [
        'erd-go' => env('LARAVEL_ERD_GO', '/usr/local/bin/erd-go'),
        'dot' => env('LARAVEL_ERD_DOT', '/usr/local/bin/dot'),
    ],
    'connections' => [],
];

などにあるので

php artisan vendor:publish --provider="Recca0120\LaravelErd\LaravelErdServiceProvider" --tag=config

でpublishできる

ルートをがっつり公開するのはさすがにまずいって話

DBの機密情報が丸見えなのでこれはやばい。個人的には

config/laravel-erd.php
<?php

return [
    'uri' => env('LARAVEL_ERD_URI', null),
    'storage_path' => storage_path('framework/cache/laravel-erd'),
    'extension' => env('LARAVEL_ERD_EXTENSION', 'sql'),
    'middleware' => [],
    'binary' => [
        'erd-go' => env('LARAVEL_ERD_GO', '/usr/local/bin/erd-go'),
        'dot' => env('LARAVEL_ERD_DOT', '/usr/local/bin/dot'),
    ],
    'connections' => [],
];

のセットを推したい。そうすればLARAVEL_ERD_URIが与えられない限り表示される事は無いだろう

右クリックのメニューがある

というか、根本的にはこれにのっけてるみたい

https://github.com/dineug/erd-editor

ここからいろいろ出来たりもする

リレーションの関係はモデル定義を見ているらしい

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }
    public function Tasks(): HasMany
    {
        return $this->hasMany(Task::class);
    }

など、正しく定義して

php artisan erd:generate

するとtask.user_iduser.idの関連が示された

type Notifications {
  users: Users
}

type Tasks {
  id: ID!
  title: String!
  description: String
  isCompleted: Int!
  dueDate: String
  createdAt: String
  updatedAt: String
  users: Users
}

type Users {
  id: ID!
  name: String!
  email: String!
  emailVerifiedAt: String
  password: String!
  rememberToken: String
  createdAt: String
  updatedAt: String
  notificationsList: [Notifications!]!
  tasksList: [Tasks!]!
}

mermaid.jsの出力

まあこれは

sqlからAIに変換してもらうのが一番早そう、というか、migrationを全部AIに食わしてもいいんでしょうけどね(元も子もないけど一応今回はパッケージの紹介だったので、このような方法を取りました)

svgにすることもできるんだけど、個人的にはあんま使わないかな

出力されたmermaid

erDiagram
  USERS {
    INT id PK
    STRING name
    STRING email
    DATETIME email_verified_at
    STRING password
    STRING remember_token
    DATETIME created_at
    DATETIME updated_at
  }

  TASKS {
    INT id PK
    INT user_id FK
    STRING title
    TEXT description
    BOOLEAN is_completed
    DATE due_date
    DATETIME created_at
    DATETIME updated_at
  }

  NOTIFICATIONS {
    INT id PK
    INT user_id FK
  }

  USERS ||--o{ TASKS : "has many"
  TASKS }o--|| USERS : "belongs to"
  USERS ||--o{ NOTIFICATIONS : "receives"
  NOTIFICATIONS }o--|| USERS : "belongs to"

Discussion