やりたいこと
Rails で、ActiveRecord::Enum
を使ってこのようなモデルを定義したとする。
class Article < ApplicationRecord
enum genre: { politics: 0, economy: 10, sports: 20, tech: 30 }
enum status: { open: 0, closed: 10 }
end
このとき、DB 上でたとえば articles.genre = 0
が何を意味するのかはプロジェクトのソースコードを触れる人間でないとわからない。
それだと開発メンバー以外が DB を分析するときに面倒なので、この手のステータスコード一覧表を自動生成して共有することにした。
また、プロジェクトでは enum_help を使い下記のようにロケールファイルを定義して enum の日本語化をしていたため(一部)、それもステータスコード一覧表に載せることにした。
ja:
enums:
article:
genre:
politics: 政治
economy: 経済
sports: スポーツ
tech: 技術
方針
今回はサクッとやりたかったのでスクリプトを書いて markdown を生成した。
(ちゃんとやるなら管理画面上で動的に生成したほうが更新に追随できてよさそう。)
やり方
このようなスクリプトを書いて status_list_generator.rb
として保存する。
# モデルを一括で読み込む
Rails.application.eager_load!
# 辞書ファイルを読み込む
I18n.t
i18ns = I18n.backend.translations[:ja][:enums].with_indifferent_access
# クラス名の辞書順に並べる
ApplicationRecord.subclasses.sort_by(&:name).each do |klass|
# テーブルカラムにない enum は無視
next if (enums = klass.defined_enums.select { |key| key.in? klass.column_names }).empty?
puts "# #{klass.table_name}"
enums.each do |column_name, enum_values|
puts "## #{column_name}"
puts '| 値 | 属性 | 日本語訳 |'
puts '| --- | --- | --- |'
enum_values.each do |label, value|
puts "| #{value} | #{label} | #{i18ns.dig(klass.name.downcase, column_name, label)} |"
end
end
end
このスクリプトを用いて
$ rails runner status_list_generator.rb > status_list.md
とすると status_list.md
に markdown でステータスコード一覧表が書き出される。こんな感じ。
# articles
## genre
| 値 | 属性 | 日本語訳 |
| --- | --- | --- |
| 0 | politics | 政治 |
| 10 | economy | 経済 |
| 20 | sports | スポーツ |
| 30 | tech | 技術 |
## status
| 値 | 属性 | 日本語訳 |
| --- | --- | --- |
| 0 | draft | |
| 10 | published | |
あとは適当な markdown プレビューを用いて出力すればよい。
筆者は Visual Studio Code の拡張機能 Markdown All in One を用いて「目次(TOC)の作成 (Create Table of Contents)」機能で目次をつけたあと、「現在のドキュメントをHTMLへ出力 (Print current document to HTML)」機能で出力した。