61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
# File 'lib/foreign_key_checker/checkers/relations.rb', line 61
def self.check_by_fks
Rails.application.eager_load!
models = ActiveRecord::Base.descendants.group_by(&:table_name)
check_relation = proc do |model, fk, association|
begin
pk = association.options[:primary_key] || model.primary_key
association.klass.table_name.to_s == fk.from_table.to_s && association.foreign_key.to_s == fk.from_column.to_s && pk.to_s == fk.to_column.to_s
rescue => e
if block_given?
yield ErrorResult.new(model: model, association: association, fk: fk, ok: false, error: e)
else
p model
p fk
p association
raise e
end
end
end
ForeignKeyChecker::Utils.get_foreign_keys_hash.each do |to_table, fks|
fks.each do |fk|
unless models.key?(fk.to_table)
result = NoModelResult.new(ok: false, table: fk.to_table)
if block_given?
yield result
else
raise result.message
end
next
end
models[fk.to_table].each do |model|
next if model.connection_specification_name != 'primary'
ok = false
ok ||= !!model.reflect_on_all_associations(:has_many).find do |association|
check_relation.call(model, fk, association)
end
ok ||= !!model.reflect_on_all_associations(:has_one).find do |association|
check_relation.call(model, fk, association)
end
if block_given?
yield HasOneOrManyResult.new(model: model, fk: fk, ok: ok)
else
raise "expected has_many or has_one association for #{fk.inspect}" if !ok
end
next if !ok
dep = false
dep ||= !!model.reflect_on_all_associations(:has_many).find do |association|
check_relation.call(model, fk, association) && association.options[:dependent]
end
dep ||= !!model.reflect_on_all_associations(:has_one).find do |association|
check_relation.call(model, fk, association) && association.options[:dependent]
end
if block_given?
yield HasOneOrManyDependentResult.new(model: model, fk: fk, ok: ok)
else
raise "expected has_many or has_one association with dependent option for #{fk.inspect}" if !dep
end
end
end
end
end
|