/
models.rb
141 lines (106 loc) · 4.03 KB
/
models.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
module RailsExtend::Models
extend self
def models_hash(root = ActiveRecord::Base)
return @models_hash if defined? @models_hash
Zeitwerk::Loader.eager_load_all
@models_hash = root.subclasses_tree
end
def models
return @models if defined? @models
Zeitwerk::Loader.eager_load_all
@models = ActiveRecord::Base.descendants
@models.reject!(&:abstract_class?)
@models
end
def reset_pk_sequence!
models.map do |i|
i.reset_pk_sequence!
end
end
def db_tables_hash
result = {}
models.group_by(&->(i) { i.connection.migrations_paths }).each do |migrations_paths, record_classes|
result[migrations_paths] = migrate_tables_hash
end
result
end
def tables_hash(root = ActiveRecord::Base, records_hash = models_hash)
@tables ||= {}
records_hash[root].each_key do |node|
next if RailsExtend.config.ignore_models.include?(node.to_s)
unless node.abstract_class?
@tables[node.table_name] ||= {}
r = @tables[node.table_name]
r[:models] ||= []
r[:models] << node unless r[:models].include?(node)
r[:table_exists] = r[:table_exists] || node.table_exists?
r[:model_attributes] ||= {}
r[:model_attributes].reverse_merge! node.migrate_attributes_by_model
r[:model_references] ||= {}
r[:model_references].reverse_merge! node.references_by_model
r[:indexes] ||= []
r[:indexes] |= node.indexes_by_model
r[:model_defaults] ||= []
r[:model_defaults] |= node.attributes_by_default
r[:belongs_attributes] ||= {}
r[:belongs_attributes].reverse_merge! node.attributes_by_belongs
if r[:model_attributes][node.primary_key.to_sym]
table_options = { id: r[:model_attributes].delete(node.primary_key.to_sym)[:migrate_type] }
r[:table_options] = table_options.inject('') { |s, h| s << ", #{h[0]}: #{h[1].inspect}" }
end
end
tables_hash(node, records_hash[root])
end
@tables
end
def migrate_tables_hash
tables = {}
tables_hash.each do |table_name, cols|
db = cols[:models][0].migrate_attributes_by_db
r = cols.slice(:indexes, :table_exists, :table_options)
r[:add_attributes] = cols[:model_attributes].except *db.keys
r[:add_references] = cols[:model_references].except *db.keys
r[:timestamps] = [:created_at, :updated_at] & r[:add_attributes].keys
r[:remove_attributes] = db.except(*cols[:model_attributes].keys, *cols[:belongs_attributes].keys, *cols[:model_defaults])
tables[table_name.to_sym] = r unless r[:add_attributes].blank? && r[:add_references].blank? && r[:remove_attributes].blank?
end
tables
end
def migrate_modules_hash
@modules = {}
models.group_by(&:module_parent).each do |module_name, record_classes|
new_prefix = (module_name.respond_to?(:table_name_prefix) && module_name.table_name_prefix) || ''
old_prefix = (module_name.respond_to?(:old_table_name_prefix) && module_name.old_table_name_prefix) || ''
record_classes.each do |record_class|
unless record_class.table_exists?
possible = record_class.table_name.sub(/^#{new_prefix}/, old_prefix)
@modules.merge! record_class.table_name => possible if tables.any?(possible)
end
end
end
arr = @modules.values
result = arr.find_all { |e| arr.rindex(e) != arr.index(e) }
warn "Please check #{result}"
@modules
end
def unbound_tables
tables - models.map(&:table_name) - ['schema_migrations', 'ar_internal_metadata']
end
def ignore_models
models.group_by(&->(i){ i.attributes_to_define_after_schema_loads.size }).transform_values!(&->(i) { i.map(&:to_s) })
end
def attachments
@attachments = {}
models.each do |model|
attaches = model.attachment_reflections.transform_values(&:macro)
@attachments.merge! model.name => attaches if attaches.present?
end
@attachments
end
def tables
ActiveRecord::Base.connection.tables
end
def model_names
models.map(&:to_s)
end
end