Class: ModelsDiagram
Overview
PrailRoady models diagram
Instance Method Summary
collapse
Methods inherited from AppDiagram
#engines, #print, #process
Constructor Details
#initialize(options = OptionsStruct.new) ⇒ ModelsDiagram
Returns a new instance of ModelsDiagram.
11
12
13
14
15
16
|
# File 'lib/prailroady/models_diagram.rb', line 11
def initialize(options = OptionsStruct.new)
super options
@graph.diagram_type = 'Models'
@habtm = []
end
|
Instance Method Details
#engine_files ⇒ Object
39
40
41
|
# File 'lib/prailroady/models_diagram.rb', line 39
def engine_files
engines.collect { |engine| Dir.glob("#{engine.root}/app/models/**/*.rb") }.flatten
end
|
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
|
# File 'lib/prailroady/models_diagram.rb', line 43
def (filename)
filename_was = filename
class_name = nil
filename = "app/models/#{filename.split('app/models')[1]}"
while filename.split('/').length > 2
begin
class_name = filename.match(%r{.*/models/(.*).rb$})[1]
class_name = class_name.camelize
class_name.constantize
break
rescue NoMethodError
class_name = nil
filename_end = filename.split('/')[2..-1]
filename_end.shift
filename = "#{filename.split('/')[0, 2].join('/')}/#{filename_end.join('/')}"
end
end
if class_name.nil?
filename_was.match(%r{.*/models/(.*).rb$})[1].camelize
else
warn class_name
class_name
end
end
|
#generate ⇒ Object
19
20
21
22
23
24
25
26
27
28
|
# File 'lib/prailroady/models_diagram.rb', line 19
def generate
warn 'Generating models diagram' if @options.verbose
get_files.each do |f|
begin
process_class (f).constantize
rescue NoMethodError
warn "Warning: exception #{$ERROR_INFO} raised while trying to load model class #{f}"
end
end
end
|
#get_files(prefix = '') ⇒ Object
30
31
32
33
34
35
36
37
|
# File 'lib/prailroady/models_diagram.rb', line 30
def get_files(prefix = '')
files = !@options.specify.empty? ? Dir.glob(@options.specify) : Dir.glob("#{prefix}app/models/**/*.rb")
files += Dir.glob('vendor/plugins/**/app/models/*.rb') if @options.plugins_models
files -= Dir.glob("#{prefix}app/models/concerns/**/*.rb") unless @options.include_concerns
files += engine_files if @options.engine_models
files -= Dir.glob(@options.exclude)
files
end
|
#include_inheritance?(current_class) ⇒ Boolean
97
98
99
100
101
102
|
# File 'lib/prailroady/models_diagram.rb', line 97
def include_inheritance?(current_class)
warn current_class.superclass if @options.verbose
(defined?(ActiveRecord::Base) ? current_class.superclass != ActiveRecord::Base : true) &&
(defined?(CouchRest::Model::Base) ? current_class.superclass != CouchRest::Model::Base : true) &&
(current_class.superclass != Object)
end
|
#process_active_record_model(current_class) ⇒ Object
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
# File 'lib/prailroady/models_diagram.rb', line 115
def process_active_record_model(current_class)
node_attribs = []
if @options.brief || current_class.abstract_class?
node_type = 'model-brief'
else
node_type = 'model'
if @options.hide_magic
magic_fields = %w[created_at created_on updated_at updated_on lock_version type id position parent_id lft rgt quote template]
magic_fields << "#{current_class.table_name}_count" if current_class.respond_to? 'table_name'
content_columns = current_class.content_columns.reject { |c| magic_fields.include? c.name }
else
content_columns = current_class.columns
end
content_columns.each do |a|
content_column = a.name
content_column += " :#{a.sql_type.to_s}" unless @options.hide_types
node_attribs << content_column
end
end
@graph.add_node [node_type, current_class.name, node_attribs]
associations = current_class.reflect_on_all_associations
if @options.inheritance && ! @options.transitive
superclass_associations = current_class.superclass.reflect_on_all_associations
associations = associations.reject { |a| superclass_associations.include? a }
end
associations.each do |a|
process_association current_class.name, a
end
true
end
|
#process_association(class_name, assoc) ⇒ Object
Process a model association
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
|
# File 'lib/prailroady/models_diagram.rb', line 275
def process_association(class_name, assoc)
warn "- Processing model association #{assoc.name}" if @options.verbose
macro = assoc.methods.to_s
return if %w[belongs_to referenced_in].include?(macro) && !@options.show_belongs_to
through = assoc.options.include?(:through)
return if through && @options.hide_through
assoc_class_name = assoc.class_name rescue nil
assoc_class_name ||= assoc.name.to_s.underscore.singularize.camelize
if assoc_class_name == assoc.name.to_s.singularize.camelize
assoc_name = ''
else
assoc_name = assoc.name.to_s
end
if class_name.include?('::') && !assoc_class_name.include?('::')
assoc_class_name = class_name.split('::')[0..-2].push(assoc_class_name).join('::')
end
assoc_class_name = assoc_class_name.gsub(/^::/, '')
if %w[has_one references_one embeds_one].include?(macro)
assoc_type = 'one-one'
elsif macro == 'has_many' && (!assoc.options[:through]) ||
%w[references_many embeds_many].include?(macro)
assoc_type = 'one-many'
elsif macro == 'belongs_to'
assoc_type = 'belongs-to'
else return if @habtm.include? [assoc_class_name, class_name, assoc_name]
assoc_type = 'many-many'
@habtm << [class_name, assoc_class_name, assoc_name]
end
@graph.add_edge [assoc_type, class_name, assoc_class_name, assoc_name]
end
|
#process_basic_class(current_class) ⇒ Object
104
105
106
107
108
|
# File 'lib/prailroady/models_diagram.rb', line 104
def process_basic_class(current_class)
node_type = @options.brief ? 'class-brief' : 'class'
@graph.add_node [node_type, current_class.name]
true
end
|
#process_basic_module(current_class) ⇒ Object
110
111
112
113
|
# File 'lib/prailroady/models_diagram.rb', line 110
def process_basic_module(current_class)
@graph.add_node ['module', current_class.name]
false
end
|
#process_class(current_class) ⇒ Object
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
# File 'lib/prailroady/models_diagram.rb', line 73
def process_class(current_class)
warn "Processing #{current_class}" if @options.verbose
generated =
if defined?(CouchRest::Model::Base) && current_class.new.is_a?(CouchRest::Model::Base)
process_couchrest_model(current_class)
elsif defined?(Mongoid::Document) && current_class.new.is_a?(Mongoid::Document)
process_mongoid_model(current_class)
elsif defined?(DataMapper::Resource) && current_class.new.is_a?(DataMapper::Resource)
process_datamapper_model(current_class)
elsif current_class.respond_to? 'reflect_on_all_associations'
process_active_record_model(current_class)
elsif @options.all && (current_class.is_a? Class)
process_basic_class(current_class)
elsif @options.modules && (current_class.is_a? Module)
process_basic_module(current_class)
end
warn generated
if @options.inheritance && generated && include_inheritance?(current_class)
@graph.add_edge ['is-a', current_class.superclass.name, current_class.name]
end
end
|
#process_couchrest_model(current_class) ⇒ Object
Some very basic CouchRest::Model support
Field types note: the field’s type is rendered only if it’s explicitly specified in a model.
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
|
# File 'lib/prailroady/models_diagram.rb', line 246
def process_couchrest_model(current_class)
node_attribs = []
if @options.brief
node_type = 'model-brief'
else
node_type = 'model'
content_columns = current_class.properties
if @options.hide_magic
magic_fields = %w[created_at updated_at type _id _rev]
content_columns = content_columns.reject { |c| magic_fields.include?(c.name) }
end
content_columns.each do |a|
content_column = a.name
content_column += " :#{a.type}" unless @options.hide_types || a.type.nil?
node_attribs << content_column
end
end
@graph.add_node [node_type, current_class.name, node_attribs]
true
end
|
#process_datamapper_model(current_class) ⇒ Object
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
|
# File 'lib/prailroady/models_diagram.rb', line 160
def process_datamapper_model(current_class)
node_attribs = []
if @options.brief node_type = 'model-brief'
else
node_type = 'model'
props = current_class.properties.sort_by(&:name)
if @options.hide_magic
magic_fields =
%w[created_at created_on updated_at updated_on lock_version _type _id position parent_id lft rgt quote template]
props = props.reject { |c| magic_fields.include?(c.name.to_s) }
end
props.each do |a|
prop = a.name.to_s
prop += " :#{a.class.name.split('::').last}" unless @options.hide_types
node_attribs << prop
end
end
@graph.add_node [node_type, current_class.name, node_attribs]
relationships = current_class.relationships
relationships.each do |a|
process_datamapper_relationship current_class.name, a
end
true
end
|
#process_datamapper_relationship(class_name, relation) ⇒ Object
Process a DataMapper relationship
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
|
# File 'lib/prailroady/models_diagram.rb', line 327
def process_datamapper_relationship(class_name, relation)
warn "- Processing DataMapper model relationship #{relation.name}" if @options.verbose
dm_type = relation.class.to_s.split('::')[-2]
return if dm_type == 'ManyToOne' && !@options.show_belongs_to
dm_parent_model = relation.parent_model.to_s
dm_child_model = relation.child_model.to_s
assoc_class_name = ''
if dm_parent_model.eql?(class_name)
assoc_class_name = dm_child_model
else
assoc_class_name = dm_parent_model
end
assoc_name = ''
unless relation.name.to_s.singularize.camelize.eql?(assoc_class_name.split('::').last)
assoc_name = relation.name.to_s
end
rel_type = 'many-many' if dm_type == 'OneToOne'
rel_type = 'one-one'
elsif dm_type == 'OneToMany'
rel_type = 'one-many'
end
@graph.add_edge [rel_type, class_name, assoc_class_name, assoc_name]
end
|
#process_mongoid_model(current_class) ⇒ Object
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
|
# File 'lib/prailroady/models_diagram.rb', line 198
def process_mongoid_model(current_class)
node_attribs = []
if @options.brief
node_type = 'model-brief'
else
node_type = 'model'
content_columns = current_class.fields.values.sort_by(&:name)
if @options.hide_magic
magic_fields = %w[created_at created_on updated_at updated_on lock_version _type _id position parent_id lft rgt quote template]
content_columns = content_columns.reject { |c| magic_fields.include?(c.name) }
end
content_columns.each do |a|
content_column = a.name
content_column += " :#{a.type}" unless @options.hide_types
node_attribs << content_column
end
end
@graph.add_node [node_type, current_class.name, node_attribs]
associations = current_class.relations.values
if @options.inheritance && !@options.transitive &&
current_class.superclass.respond_to?(:relations)
associations -= current_class.superclass.relations.values
end
associations.each do |a|
process_association current_class.name, a
end
true
end
|