Open6

RailsのER図をFigjamでガチャガチャできるようにして設計議論をしやすくしたい

funwarioisiifunwarioisii

やりたいこと

Figjamで設計について議論したりしやすくしたい

ピンクの部分が自動で生成されると、青の部分でこんなモデル追加すると良いんじゃない?とか話しやすい
モデルの数が増えるほど、手で書き起こすのは大変なので。

知ってたこと

  • rails-erd でER図のpdf を吐いたり、 dot形式で出力できる
  • Figma の plugin はTypeScript で開発できる

最初に思ってた進め方

  1. 多分 rails-erd-mermaid みたいな gem で ER図を mermaid で吐けよう
  2. 多分 mermaid のライブラリで mermaid.parse(text) とかしたらいい感じの中間表現が得られよう
  3. そしたら後は表示だけ頑張ればよかろう
funwarioisiifunwarioisii

Rails で ER図を mermaid として出力

https://zenn.dev/koedame/articles/ac4815887325ef

というブログを発見
いい感じだなーと思って、 gem を読むと

  1. モデルの関係を読む
  2. モデルとその関係をハッシュオブジェクトとしてフロントエンドに渡す
  3. フロントエンドで mermaid として組み立てる

というのをやっていた。
mermaid にした結果を私は CLI 上で知りたかったのでちょっとユースケースが異なる

ので、一旦プロトタイプを作ってみた

https://github.com/funwarioisii/rails_erd_mermaid

以下のように使える

lib/tasks/erd.thor に↓

# frozen_string_literal: true

class Erd < Thor
  default_command :export

  desc "export_mermaid", "Generate a mermaid file from your database"
  option :filetype, default: "mermaid", desc: "Filetype to export. It is used for file extension."
  option :dir_name, default: "mermaid_erd", desc: "Directory name to export"
  option :file_name, default: "erd", desc: "File name to export"
  def export_mermaid
    config = RailsErdMermaid::Config.new(**options)
    app = RailsErdMermaid::App.new(config)
    app.export
  end
end

schema.rbを抜粋

  create_table "comments", force: :cascade do |t|
    t.string "body"
    t.integer "user_id", null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["user_id"], name: "index_comments_on_user_id"
  end

  create_table "users", force: :cascade do |t|
    t.string "name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

これで bundle exec thor erd:export_mermaid を実行すると erd_mermaid/erd.mermaid

erDiagram
  Comment {
    id integer PK
    body string 
    user_id integer FK
    created_at datetime 
    updated_at datetime 
  }
  User {
    id integer PK
    name string 
    created_at datetime 
    updated_at datetime 
  }
  User o{--|| Comment : user

と出力される

funwarioisiifunwarioisii

mermaid で書かれたテキストをパースした結果を得る

mermaid.parse(text) で得られるのは Promise<boolean> で、他にもいろいろ読んでみたけど、いい感じの中間表現は得られなさそうだった

https://github.com/mermaid-js/mermaid/issues/4 で10年前に起票されており、5年前からプロジェクトが始動しているのを感じる

そろそろ出てきそうな波動は↓で感じられる
https://github.com/mermaid-js/mermaid/tree/next/packages/parser

npm もあるが v0.1.0 とか
https://www.npmjs.com/package/@mermaid-js/parser

導入しようとしたが残念ながら linguim 周りの型エラーが大変で一旦手を退けた

↓も見つけたが
https://www.npmjs.com/package/mermaid-parser

を見ると ER図は対応していないし、この開発者はさっき mermaid-js/parser にコミットしてるのを見かけた気がする
https://github.com/Yokozuna59/mermaid-lint/tree/master/packages/mermaid-parser

funwarioisiifunwarioisii

ということで思ったより簡単にできなかった;;

方針転換を考えると

  1. mermaid に SVG を吐かせて、figma.createNodeFromSvg(svg) で SVG を表示する
  2. 独自で parser を作る
  3. mermaid を諦める

あたりか。

「1. mermaid に SVG を吐かせて、figma.createNodeFromSvg(svg) で SVG を表示する」は簡単かつ汎用性が高そう。
やってみると以下のように黒つぶれしてしまいうまくならなかった。

SVGをこねる方向で進めるか?

「2. 独自で parser を作る」は筋悪な感じがするがやってみたい気がする

「3. mermaid を諦める」は趣旨に反するが、まともな判断な気がする

とりあえず 「2. 独自で parser を作る」 で進める