Browse documentationOpen

byrcsc/laravel-cartographer · 1.x

Diagrams per subsystem.

Generate a set of scoped diagrams in one pass, embed them in existing documentation, and cover applications that span several database connections.

One diagram per repository stops working somewhere around forty tables. The fix is a full diagram as the reference, plus a small scoped diagram beside each piece of documentation that needs one.

Generate a set in one pass

Put the scopes in a script and run them together:

#!/usr/bin/env bash
set -euo pipefail

php artisan cartographer:erd \
  --output=docs/erd.md

php artisan cartographer:erd \
  --models=Post,Category \
  --depth=1 --columns=keys \
  --output=docs/erd-publishing.md

php artisan cartographer:erd \
  --models=Invoice,Payment \
  --depth=1 --columns=keys \
  --output=docs/erd-billing.md

php artisan cartographer:erd \
  --models=User \
  --depth=1 --columns=keys \
  --output=docs/erd-accounts.md

Save it as bin/erd, make it executable, and wire it into Composer so nobody has to remember the flags:

{
  "scripts": {
    "erd": "bin/erd"
  }
}
composer erd

Each invocation reads the schema again. On a schema of a few hundred tables that is a second or so per diagram, which is fine for four and worth reconsidering at forty — at that point, drive the pipeline once and render several graphs from one schema read. See PHP API.

Choose the scope per audience

DiagramScopeReader
Full referenceNo seeds, --columns=allAnyone tracing a column
SubsystemSeeds plus --depth=1, --columns=keysSomeone changing that subsystem
OrientationNo seeds, --columns=noneSomeone new to the codebase

The orientation diagram is the one people underrate. With --columns=none the output is entity names and edges, which fits on a screen for applications where the full diagram does not.

Embed a diagram in an existing page

--format=mmd writes the raw Mermaid with no Markdown wrapper, which is what you want when the diagram goes inside a page you already maintain:

php artisan cartographer:erd \
  --models=Invoice --depth=1 --columns=keys \
  --format=mmd \
  --output=docs/diagrams/billing.mmd

Most static site generators can include a file into a fenced block. If yours cannot, generate to stdout and assemble the page in the script:

{
  cat docs/partials/billing-intro.md
  echo '```mermaid'
  php artisan cartographer:erd --models=Invoice --depth=1 --format=mmd --stdout
  echo '```'
} > docs/billing.md

--stdout suppresses warnings and the summary line, so nothing but the diagram reaches the pipe.

Render to an image

The package writes text and stops there. To get a PNG or SVG, hand the .mmd file to the Mermaid CLI:

php artisan cartographer:erd --format=mmd --output=docs/erd.mmd
npx -y @mermaid-js/mermaid-cli -i docs/erd.mmd -o docs/erd.svg

Do this in a documentation build rather than committing the image. Committed binaries do not diff, which throws away the main reason for generating the diagram from source.

Applications with several connections

Each run introspects exactly one connection. An application whose models are split across connections needs one run per connection, and the model list needs splitting to match:

php artisan cartographer:erd \
  --connection=mysql \
  --output=docs/erd-app.md

php artisan cartographer:erd \
  --connection=reporting \
  --models=Warehouse,FactOrder --depth=1 \
  --output=docs/erd-reporting.md

Without the seeds, the second run would try every discovered model against the reporting connection and warn about each table that is not there. Seeding is what keeps the output clean.

There is no cross-connection diagram. An edge needs both tables on the connection being read, so a relation that spans connections produces no edge on either side.