Skip to content

Instantly share code, notes, and snippets.

@alpaca-tc
Created May 23, 2021 12:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alpaca-tc/6a6c024b11a2a0e09713b510362e6bd2 to your computer and use it in GitHub Desktop.
Save alpaca-tc/6a6c024b11a2a0e09713b510362e6bd2 to your computer and use it in GitHub Desktop.
定義漏れの外部キーを自動検知する
# frozen_string_literal: true
RSpec.describe 'ActiveRecord foreign key' do
let(:connection) { ActiveRecord::Base.connection }
let(:tables) { connection.tables }
def foreign_key_exists?(reflection, foreign_keys)
to_table_name = reflection.klass.table_name
reflection.foreign_key
foreign_keys.any? do |foreign_key|
foreign_key.to_table == to_table_name && foreign_key.column == reflection.foreign_key
end
end
# テスト対象外にするテーブル一覧
# [table_names, ...]
let(:ignored_tables) do
%w[]
end
it 'detects missing foreign keys' do
missing_reflections = []
(tables - ignored_tables).each do |table_name|
foreign_keys = connection.foreign_keys(table_name)
class_name = table_name.singularize.classify
klass = class_name.constantize
reflections = klass.reflect_on_all_associations(:belongs_to)
reflections.reject!(&:polymorphic?)
reflections.each do |reflection|
next if foreign_key_exists?(reflection, foreign_keys)
missing_reflections.push(
[table_name, reflection]
)
end
end
expect(missing_reflections).to be_empty, -> {
missing_keys = missing_reflections.map do |(table_name, reflection)|
"add_foreign_key(:#{table_name}, :#{reflection.klass.table_name})"
end
<<~EOS
Not found foreigin key.
#{missing_keys.join("\n")}
EOS
}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment