21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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
|
# File 'lib/dige/instantiator/rails3.rb', line 21
def load_klasses
klasses = Dige::Klasses.new
parent_child_relations = Dige::ParentChildRelations.new
associations = Dige::Associations.new
ActiveRecord::Base.subclasses.each do |klass|
columns = ActiveRecord::Base.connection.table_exists?(klass.table_name) ? klass.columns.collect { |column| column.name.to_s } : []
klasses.register(klass.name, klass.table_name, columns) unless Dige::IGNORE_CLASSES.include?(klass.name)
parent_child_relations.register(klass.superclass.name, klass.name) unless Dige::IGNORE_CLASSES.include?(klass.superclass.name) || Dige::IGNORE_CLASSES.include?(klass.name)
end.each do |klass|
klass.reflect_on_all_associations.each do |assoc|
type = assoc.options[:polymorphic] ? :polymorphic : :normal
next if assoc.options[:through] || Dige::IGNORE_CLASSES.include?(klass.name)
if type == :polymorphic &&
(!klasses[klass.name].columns.include?((assoc.options[:foreign_key] || "#{assoc.name.to_s}_id").to_s) ||
!klasses[klass.name].columns.include?((assoc.options[:foreign_type] || "#{assoc.name.to_s}_type").to_s))
$stderr.puts "warning: class #{klass.name} defines a polymorphic relationship #{assoc.name.to_s}, for which there are not the necessary columns in the DB."
next
end
assoc_class_name = if type == :polymorphic
assoc.name.to_s
elsif assoc.options[:class_name]
assoc.options[:class_name].to_s
else
if assoc.macro == :has_many || assoc.macro == :has_and_belongs_to_many
assoc.name.to_s.singularize.camelize
else
assoc.name.to_s.camelize
end
end
next if Dige::IGNORE_CLASSES.include?(assoc_class_name)
if klasses[assoc_class_name].nil? && type != :polymorphic
polymorphic_name = (assoc.options[:foreign_key] || assoc.options[:foreign_type] || "").to_s.gsub(/_(id|type)$/, '')
if !polymorphic_name.empty? &&
(klasses[klass.name].columns.include?("#{polymorphic_name}_id")) &&
(klasses[klass.name].columns.include?("#{polymorphic_name}_type"))
assoc_class_name = polymorphic_name
type = :polymorphic
else
$stderr.puts "warning: class #{klass.name} references non-existing class #{assoc_class_name}" unless assoc.options[:through]
next
end
end
assoc_table_name = klasses[assoc_class_name].table_name unless type == :polymorphic
associations.register(klass.name, klass.table_name, assoc_class_name, assoc_table_name, type, assoc.macro, assoc.options[:join_table])
end
end
associations.all(:polymorphic).each do |assoc|
polymorphic_klasses = ActiveRecord::Base.connection.select_values("SELECT DISTINCT #{assoc.to_class_name}_type FROM #{assoc.from_table_name};").compact
klasses.all.each do |klass|
next unless polymorphic_klasses.include?(klass.class_name)
associations.register(assoc.from_class_name, assoc.from_table_name, klass.class_name, klass.table_name, :normal, assoc.macro, assoc.table_name)
end
end
associations.all.each do |assoc|
klasses[assoc.from_class_name].associations_count += 1
klasses[assoc.to_class_name].associations_count += 1
end
{
:klasses => klasses,
:parent_child_relations => parent_child_relations,
:associations => associations
}
end
|