この記事は Rails 5.1 で確認したものです。
voormedia/rails-erd は Graphviz を利用してER図を自動で出力してくれる便利な gem ですが、普段我々がメンテするような規模のアプリケーションのER図を出力すると以下のようになってしまって目が潰れてしまいます。ドキュメントは自動生成されたもの以外信じられないとはいえ、読めないのでは意味がありません。
例としてあげるこの ER図は solidusio/solidus のものです。
このような見るに堪えないER図は出力しても仕方ないのでもう少し読みやすいER図を出力しましょう。
- ファイル名を特定のモデル名に
- ER図に出力するモデルは 1. とリレーションが定義されているモデルのみにする
- このER図を全モデル分作る
という戦略で行きたいと思います。以下のようなスクリプトを書いて動かします。development 環境の場合は Rails.application.eager_load!
で定数の先読みをしましょう。
Rails.application.eager_load!
ApplicationRecord.descendants.map do |k|
[ k.name, k.reflect_on_all_associations.map { |a| a.class_name }].flatten
end.map do |models|
puts %(bundle exec erd --only=#{models.join(",")} --filename=tmp/#{models.first})
end
この出力を適当なファイルに出力して実行しましょう。数が多いので並列実行すると時間の節約になると思います。
bundle exec rails runner '
Rails.application.eager_load!
ActiveRecord::Base.descendants.map do |k|
[ k.name,
k.reflect_on_all_associations.map do |a|
# 異なる名前空間に同じクラス名のモデルが存在した場合で、リレーションの指定で空間の省略をおこなった場合
# 無条件で名前同じ名前空間のクラス名を無条件に設定しています。
# これで不都合がおこる場合は、なんとかする方法を考えましょう。
namespace = k.name.deconstantize.blank? ? "" : k.name.deconstantize + "::"
namespaced = "#{namespace}#{a.class_name}"
Module.const_defined?(namespaced) ? namespaced : a.class_name
end
].flatten
end.map do |models|
puts %(bundle exec erd --only=#{models.join(",")} --filename=tmp/#{models.first} --title=#{models.first})
end
' 2>/dev/null | grep erd > tmp/hoge.sh
cat tmp/hoge.sh | xargs -I{} -P 8 bash -x -c {}
するとこのような「半径1ホップ分の」ER図ができあがります。
これならなんとか僕でも読めそうです。
まとめ
amatsuda/erd を使いましょう。