🐈

Github Actionsを使用してRailsのenumをマークダウンに出力した話

2023/03/20に公開

こんにちは、みてねコールドクターでエンジニアマネージャーをしている遠藤です。

今回は、Github Actionsを使用して、Railsのenumが追加または更新されたときに、その定義を自動的にマークダウンに出力する方法について紹介します。

背景

弊社では、Railsのenumを使用して、モデルの定義をしています。
enumはわかりやすい名前をつけて、定義をしてくれたり、更新、値の確認メソッドなどを自動で作成してくれるので、便利です。
しかし、enumで定義された値は、SQL分析時には数値に変換されてしまうため、値を確認するときには、enumの定義を確認する必要があります。
これを解決するため、Github Actionsを使用し、enumの定義をマークダウンに出力するようにしました。

実装

前提として、localeファイルにカラムenumの日本語訳を用意しています。
enumの定義をマークダウンに出力するために、以下のようなRakeタスクを作成しました。

lib/tasks/system/enum_list_generator.rake
namespace :enum_list_generator do
  desc 'enumの状態リストを生成する'
  task execute: :environment do
    # モデルを一括で読み込む
    Rails.application.eager_load!
    # 辞書ファイルを読み込む
    I18n.t
    rows = []

    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?

      rows << "# #{klass.table_name}"
      enums.each do |column_name, enum_values|
        rows << "## #{column_name}"
        rows << '| 値 | 属性 | 日本語訳 |'
        rows << '| --- | --- | --- |'
        enum_values.each do |label, value|
          rows << "| #{value} | #{label} | #{i18ns.dig(klass.name.underscore, column_name, label)} |"
        end
      end
    end

    doc_dir = 'doc/schema/enum_list'
    FileUtils.mkdir_p(doc_dir)

    File.write("#{doc_dir}/README.md", rows.join("\n"))
  end
end

次に、これをGithub Actionsで実行します。以下はGithub Actionsの一部です。
(スキーマをloadしたりすることは、別途設定してください)

name: enum_list_generator
on:
  push:
    paths:
      - app/models/*.rb
      - config/locales/models/**/*.yml

  jobs:
    色々省略
      - name: Execute enum_list_generator
        run: |
          bin/rails enum_list_generator:execute

      - name: Count changed or untracked files
        id: check_diff
        run: |
          git status --porcelain | wc -l
          file_count=$(git status --porcelain | wc -l)
          echo "::set-output name=file_count::$file_count"

      - name: Commit Enum list graph
        if: ${{ steps.check_diff.outputs.file_count != '0' }}
        run: |
          git config user.name github-actions
          git config user.email github-actions@github.com
          git add doc/schema/enum_list/README.md
          git commit -m "generate Enum list from actions"
          git push

Rakeタスクを実行し、diffを確認し、diffがあればcommitしてpushします。
これで、enumの定義が更新された時に、マークダウンに出力されるようになりました。

まとめ

自動更新するようになったので、運用の手間が減り、また1つのファイルで最新の状態を確認することができます。
弊社では、tblsを使用してDBのスキーマをマークダウンに出力し、docフォルダ以下を見ればDBの定義がわかるようにしています。

何でも自動化して運用の手間を減らすのが好きなエンジニアを募集しています。

参考

【Rails】enum で管理されているプロパティについて、属性と DB 上の値との対応表を作る

みてねコールドクターテックブログ

Discussion