packwerk下のModelでアノテーションを表示する
はじめに
こんにちは。春から担当チームが変更となりクリニックDX支援チームからバックエンド基盤チームに移動した山本です。前回の力作ブログ「packs-rails + packwerkでファットモデルを安全に分割する」は読んでいただけましたでしょうか?バックエンド基盤チームでは「プロダクト間のコード依存を解消し、プロダクトチームの生産効率向上に貢献する」をミッションに掲げ packwerkを使ったRailsアプリケーションのモジュラーモノリス化の推進を行っています。
annotationを使いたい
弊社のrailsプロジェクトでは annotate.gemを使ってModelにTableの項目名を表示しています。
アノテーションの例
このgemを利用することで、DBマイグレーション後にコメント形式でModelの先頭にカラム名が挿入されます。
しかし、packwerkで管理されているパッケージ下のModelではこの機能がうまく動作しない問題がありました。
調査
設定ファイルを確認する
annotate.gem
をインストール後、 rails g annotate:install
を行うことで、 lib/tasks/auto_annotate_models.rake
が作成されます。デフォルトの設定項目を眺めていると model_dir
と root_dir
という項目が見つかりました。このあたりの設定を変更すれば対応できそうな匂いがします。
コードの調査と実験
コードを追っていくと、どうやら model_dir
や root_dir
はカンマ区切りに対応しているようです。
試しに、reservationパッケージを指定してみます。
# NOTE: only doing this in development as some production environments (Heroku)
# NOTE: are sensitive to local FS writes, and besides -- it's just not proper
# NOTE: to have a dev-mode tool do its thing in production.
if Rails.env.development?
require 'annotate'
task :set_annotation_options do
# You can override any of these by setting an environment variable of the
# same name.
Annotate.set_defaults(
(略)
'model_dir' => 'app/models,packs/reservation/app/models',
'root_dir' => ',packs/reservation',
(略)
)
end
Annotate.load_tasks
end
rake db:migrate
を実行するとパッケージ下のModelやrspecにもアノテーションが設定されました🎉
汎用的に利用できるように改修
今のままだとパッケージが追加されるたびにrakeファイルの修正が必要となります。以下のようにコードを修正して自動的にパッケージ化のモデルを認識するようにしてみました。
# NOTE: only doing this in development as some production environments (Heroku)
# NOTE: are sensitive to local FS writes, and besides -- it's just not proper
# NOTE: to have a dev-mode tool do its thing in production.
if Rails.env.development?
require 'annotate'
task :set_annotation_options do
# You can override any of these by setting an environment variable of the
# same name.
defaults = {
(略)
'model_dir' => 'app/models',
'root_dir' => '',
(略)
}
# パッケージ下のファイルにもアノテーションが効くよう調整する
Packs.all.each do |pack|
model_dir_path = "#{pack.name}/app/models"
defaults['model_dir'] += ",#{model_dir_path}" if Dir.exist?(Rails.root.join(model_dir_path))
defaults['root_dir'] += ",#{pack.name}"
end
Annotate.set_defaults(defaults)
end
Annotate.load_tasks
end
パッケージの一覧はPackwerkの機能を使うと Packs.all
で取得できます。この内容を元に model_dir
と root_dir
に追加してみました。これで、パッケージの追加を意識すること無く自動でアノテーションが記載されます。
まとめ
- packwerkを使うと、そのままではパッケージ下のファイルにannotate.gemが適用されない。
-
lib/tasks/auto_annotate_models.rake
に書かれている設定を動的に作成することで対応できた。
annotate.gemはRailsプロジェクトで広く使われているGemだと認識しています。モジュラーモノリス化に合わせて設定してみてくださいね。
Discussion