➡
Railsのアソシエーションのタイポを検出する
歴史あるRailsアプリではアソシエーションにタイポがある
何年も経過したRailsのアプリケーションをメンテナンスをしていると、自分が知らないクラスはたくさんあります。
そしてクラス同士の関連を示すアソシエーションは、クラス自体よりも多くあったりもします。
その中で意外と見つけにくいのが、アソシエーションのタイポです。
なぜなら、全く使っていないならば動かないのでエラーも発生しないためです。
これはActiveRecordがRubyの動的な仕組みを活かして実装されていることが原因です。
最初にModelを定義したときに、とりあえず設定しておいたアソシエーションが、使われないままサービスが動いていることはよくあることですね。
しかし、問題は発生していなくとも、いざ機能を修正する際に触ることもあるでしょう。
その前に検知できていれば、驚くことも減るのではないでしょうか?
そんなときに使えるスクリプトを作ったので共有します。
検出スクリプト
require 'rails'
# Railsアプリケーションをロードする
require File.expand_path('config/environment', __dir__)
# すべてのモデルをロードする
Rails.application.eager_load!
# モデル情報を取得する
ActiveRecord::Base.descendants.each do |model|
next if model == ActiveRecord::SchemaMigration # SchemaMigrationモデルはスキップ
model.reflect_on_all_associations.each do |association|
begin
association_name = association.name
# タイポしていると該当するclass名が無くて例外発生
association.class_name
rescue NoMethodError => e
puts "Model: #{model.name}"
puts " Association Name: #{association_name}"
puts
end
end
end
実行は以下のように runner で行います。
rails runner association_checker.rb
結果は以下のように出てきます。
このModelのアソシエーション部分を見てみると、何かしらのタイポや設定ミスが見つかるはずです。
手元のリポジトリではuser
がusr
となってしまっていた箇所などを検知できました。
Model: Hoge
Association Name: hogehoge
Model: Fuga
Association Name: fugafuga
スクリプトはgistにも上げています。
Discussion