railroady 1.0.4 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +1 -1
- data/VERSION.yml +1 -1
- data/lib/railroady/diagram_graph.rb +2 -2
- data/lib/railroady/models_diagram.rb +141 -80
- metadata +4 -4
data/README.rdoc
CHANGED
@@ -27,7 +27,7 @@ Ubuntu users can install in via `sudo apt-get install graphviz`.
|
|
27
27
|
The easiest (and recommend) usage is to include railroady as a development dependency with your Rails 3 Gemfile, like so...
|
28
28
|
|
29
29
|
group :development, :test do
|
30
|
-
|
30
|
+
gem 'railroady'
|
31
31
|
end
|
32
32
|
|
33
33
|
...and then run the master rake task...
|
data/VERSION.yml
CHANGED
@@ -66,8 +66,8 @@ class DiagramGraph
|
|
66
66
|
return "\t_diagram_info [shape=\"plaintext\", " +
|
67
67
|
"label=\"#{@diagram_type} diagram\\l" +
|
68
68
|
"Date: #{Time.now.strftime "%b %d %Y - %H:%M"}\\l" +
|
69
|
-
"Migration version: " +
|
70
|
-
|
69
|
+
(defined?(ActiveRecord::Migrator) ? "Migration version: " +
|
70
|
+
"#{ActiveRecord::Migrator.current_version}\\l" : "") +
|
71
71
|
"Generated by #{APP_HUMAN_NAME} #{APP_VERSION}\\l"+
|
72
72
|
"http://railroady.prestonlee.com" +
|
73
73
|
"\\l\", fontsize=13]\n"
|
@@ -8,10 +8,8 @@ require 'railroady/app_diagram'
|
|
8
8
|
|
9
9
|
# RailRoady models diagram
|
10
10
|
class ModelsDiagram < AppDiagram
|
11
|
-
|
12
11
|
def initialize(options = OptionsStruct.new)
|
13
|
-
|
14
|
-
super options
|
12
|
+
super options
|
15
13
|
@graph.diagram_type = 'Models'
|
16
14
|
# Processed habtm associations
|
17
15
|
@habtm = []
|
@@ -19,12 +17,12 @@ class ModelsDiagram < AppDiagram
|
|
19
17
|
|
20
18
|
# Process model files
|
21
19
|
def generate
|
22
|
-
STDERR.
|
20
|
+
STDERR.puts "Generating models diagram" if @options.verbose
|
23
21
|
get_files.each do |f|
|
24
22
|
begin
|
25
23
|
process_class extract_class_name(f).constantize
|
26
24
|
rescue Exception
|
27
|
-
STDERR.
|
25
|
+
STDERR.puts "Warning: exception #{$!} raised while trying to load model class #{f}"
|
28
26
|
end
|
29
27
|
|
30
28
|
end
|
@@ -39,92 +37,154 @@ class ModelsDiagram < AppDiagram
|
|
39
37
|
|
40
38
|
# Process a model class
|
41
39
|
def process_class(current_class)
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
if current_class.respond_to?'reflect_on_all_associations'
|
49
|
-
|
50
|
-
|
51
|
-
node_attribs = []
|
52
|
-
if @options.brief || current_class.abstract_class?
|
53
|
-
node_type = 'model-brief'
|
54
|
-
else
|
55
|
-
node_type = 'model'
|
56
|
-
|
57
|
-
# Collect model's content columns or all columns if all_columns flag is passed
|
58
|
-
if @options.all_columns
|
59
|
-
columns = current_class.columns
|
60
|
-
else
|
61
|
-
columns = current_class.content_columns
|
62
|
-
end
|
63
|
-
|
64
|
-
if @options.hide_magic
|
65
|
-
# From patch #13351
|
66
|
-
# http://wiki.rubyonrails.org/rails/pages/MagicFieldNames
|
67
|
-
magic_fields = [
|
68
|
-
"created_at", "created_on", "updated_at", "updated_on",
|
69
|
-
"lock_version", "type", "id", "position", "parent_id", "lft",
|
70
|
-
"rgt", "quote", "template"
|
71
|
-
]
|
72
|
-
magic_fields << current_class.table_name + "_count" if current_class.respond_to? 'table_name'
|
73
|
-
columns = current_class.content_columns.select {|c| ! magic_fields.include? c.name}
|
74
|
-
end
|
75
|
-
|
76
|
-
columns.each do |a|
|
77
|
-
column = a.name
|
78
|
-
column += ' :' + a.type.to_s unless @options.hide_types
|
79
|
-
node_attribs << column
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
@graph.add_node [node_type, current_class.name, node_attribs]
|
84
|
-
generated = true
|
85
|
-
# Process class associations
|
86
|
-
associations = current_class.reflect_on_all_associations
|
87
|
-
if @options.inheritance && ! @options.transitive
|
88
|
-
superclass_associations = current_class.superclass.reflect_on_all_associations
|
89
|
-
|
90
|
-
associations = associations.select{|a| ! superclass_associations.include? a}
|
91
|
-
# This doesn't works!
|
92
|
-
# associations -= current_class.superclass.reflect_on_all_associations
|
93
|
-
end
|
94
|
-
associations.each do |a|
|
95
|
-
process_association current_class.name, a
|
96
|
-
end
|
40
|
+
STDERR.puts "Processing #{current_class}" if @options.verbose
|
41
|
+
|
42
|
+
generated = if defined?(Mongoid::Document) && current_class.new.is_a?(Mongoid::Document)
|
43
|
+
process_mongoid_model(current_class)
|
44
|
+
elsif current_class.respond_to?'reflect_on_all_associations'
|
45
|
+
process_active_record_model(current_class)
|
97
46
|
elsif @options.all && (current_class.is_a? Class)
|
98
|
-
|
99
|
-
node_type = @options.brief ? 'class-brief' : 'class'
|
100
|
-
@graph.add_node [node_type, current_class.name]
|
101
|
-
generated = true
|
47
|
+
process_basic_class(current_class)
|
102
48
|
elsif @options.modules && (current_class.is_a? Module)
|
103
|
-
|
49
|
+
process_basic_module(current_class)
|
104
50
|
end
|
105
51
|
|
106
|
-
|
107
|
-
if @options.inheritance && generated &&
|
108
|
-
(current_class.superclass != ActiveRecord::Base) &&
|
109
|
-
(current_class.superclass != Object)
|
52
|
+
if @options.inheritance && generated && include_inheritance?(current_class)
|
110
53
|
@graph.add_edge ['is-a', current_class.superclass.name, current_class.name]
|
111
54
|
end
|
112
|
-
|
55
|
+
|
113
56
|
end # process_class
|
57
|
+
|
58
|
+
def include_inheritance?(current_class)
|
59
|
+
(defined?(ActiveRecord::Base) && current_class.superclass != ActiveRecord::Base) &&
|
60
|
+
(current_class.superclass != Object)
|
61
|
+
end
|
62
|
+
|
63
|
+
def process_basic_class(current_class)
|
64
|
+
node_type = @options.brief ? 'class-brief' : 'class'
|
65
|
+
@graph.add_node [node_type, current_class.name]
|
66
|
+
true
|
67
|
+
end
|
68
|
+
|
69
|
+
def process_basic_module(current_class)
|
70
|
+
@graph.add_node ['module', current_class.name]
|
71
|
+
false
|
72
|
+
end
|
73
|
+
|
74
|
+
def process_active_record_model(current_class)
|
75
|
+
node_attribs = []
|
76
|
+
if @options.brief || current_class.abstract_class?
|
77
|
+
node_type = 'model-brief'
|
78
|
+
else
|
79
|
+
node_type = 'model'
|
80
|
+
|
81
|
+
# Collect model's content columns
|
82
|
+
content_columns = current_class.content_columns
|
83
|
+
|
84
|
+
if @options.hide_magic
|
85
|
+
# From patch #13351
|
86
|
+
# http://wiki.rubyonrails.org/rails/pages/MagicFieldNames
|
87
|
+
magic_fields = [
|
88
|
+
"created_at", "created_on", "updated_at", "updated_on",
|
89
|
+
"lock_version", "type", "id", "position", "parent_id", "lft",
|
90
|
+
"rgt", "quote", "template"
|
91
|
+
]
|
92
|
+
magic_fields << current_class.table_name + "_count" if current_class.respond_to? 'table_name'
|
93
|
+
content_columns = current_class.content_columns.select {|c| ! magic_fields.include? c.name}
|
94
|
+
else
|
95
|
+
content_columns = current_class.content_columns
|
96
|
+
end
|
97
|
+
|
98
|
+
content_columns.each do |a|
|
99
|
+
content_column = a.name
|
100
|
+
content_column += ' :' + a.type.to_s unless @options.hide_types
|
101
|
+
node_attribs << content_column
|
102
|
+
end
|
103
|
+
end
|
104
|
+
@graph.add_node [node_type, current_class.name, node_attribs]
|
105
|
+
|
106
|
+
# Process class associations
|
107
|
+
associations = current_class.reflect_on_all_associations
|
108
|
+
if @options.inheritance && ! @options.transitive
|
109
|
+
superclass_associations = current_class.superclass.reflect_on_all_associations
|
110
|
+
|
111
|
+
associations = associations.select{|a| ! superclass_associations.include? a}
|
112
|
+
# This doesn't works!
|
113
|
+
# associations -= current_class.superclass.reflect_on_all_associations
|
114
|
+
end
|
115
|
+
|
116
|
+
associations.each do |a|
|
117
|
+
process_association current_class.name, a
|
118
|
+
end
|
119
|
+
|
120
|
+
true
|
121
|
+
end
|
122
|
+
|
123
|
+
def process_mongoid_model(current_class)
|
124
|
+
node_attribs = []
|
125
|
+
|
126
|
+
if @options.brief
|
127
|
+
node_type = 'model-brief'
|
128
|
+
else
|
129
|
+
node_type = 'model'
|
130
|
+
|
131
|
+
# Collect model's content columns
|
132
|
+
content_columns = current_class.fields.values.sort_by(&:name)
|
133
|
+
|
134
|
+
if @options.hide_magic
|
135
|
+
# From patch #13351
|
136
|
+
# http://wiki.rubyonrails.org/rails/pages/MagicFieldNames
|
137
|
+
magic_fields = [
|
138
|
+
"created_at", "created_on", "updated_at", "updated_on",
|
139
|
+
"lock_version", "_type", "_id", "position", "parent_id", "lft",
|
140
|
+
"rgt", "quote", "template"
|
141
|
+
]
|
142
|
+
content_columns = content_columns.select {|c| !magic_fields.include?(c.name) }
|
143
|
+
end
|
144
|
+
|
145
|
+
content_columns.each do |a|
|
146
|
+
content_column = a.name
|
147
|
+
content_column += " :#{a.type}" unless @options.hide_types
|
148
|
+
node_attribs << content_column
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
@graph.add_node [node_type, current_class.name, node_attribs]
|
153
|
+
|
154
|
+
# Process class associations
|
155
|
+
associations = current_class.relations.values
|
156
|
+
|
157
|
+
if @options.inheritance && !@options.transitive &&
|
158
|
+
current_class.superclass.respond_to?(:relations)
|
159
|
+
associations -= current_class.superclass.relations.values
|
160
|
+
end
|
161
|
+
|
162
|
+
associations.each do |a|
|
163
|
+
process_association current_class.name, a
|
164
|
+
end
|
165
|
+
|
166
|
+
true
|
167
|
+
end
|
168
|
+
|
114
169
|
|
115
170
|
# Process a model association
|
116
171
|
def process_association(class_name, assoc)
|
117
|
-
|
118
|
-
STDERR.print "\t\tProcessing model association #{assoc.name.to_s}\n" if @options.verbose
|
172
|
+
STDERR.puts "- Processing model association #{assoc.name.to_s}" if @options.verbose
|
119
173
|
|
120
174
|
# Skip "belongs_to" associations
|
121
|
-
|
122
|
-
|
175
|
+
macro = assoc.macro.to_s
|
176
|
+
return if %w[belongs_to referenced_in].include?(macro) && !@options.show_belongs_to
|
177
|
+
|
178
|
+
#TODO:
|
179
|
+
# FAIL: assoc.methods.include?(:class_name)
|
180
|
+
# FAIL: assoc.responds_to?(:class_name)
|
181
|
+
assoc_class_name = assoc.class_name rescue nil
|
182
|
+
assoc_class_name ||= assoc.name.to_s.underscore.singularize.camelize
|
183
|
+
|
123
184
|
# Only non standard association names needs a label
|
124
185
|
|
125
186
|
# from patch #12384
|
126
187
|
# if assoc.class_name == assoc.name.to_s.singularize.camelize
|
127
|
-
assoc_class_name = (assoc.class_name.respond_to? 'underscore') ? assoc.class_name.underscore.camelize : assoc.class_name
|
128
188
|
if assoc_class_name == assoc.name.to_s.singularize.camelize
|
129
189
|
assoc_name = ''
|
130
190
|
else
|
@@ -137,18 +197,19 @@ class ModelsDiagram < AppDiagram
|
|
137
197
|
end
|
138
198
|
assoc_class_name.gsub!(%r{^::}, '')
|
139
199
|
|
140
|
-
if [
|
200
|
+
if %w[has_one references_one embeds_one].include?(macro)
|
141
201
|
assoc_type = 'one-one'
|
142
|
-
elsif
|
202
|
+
elsif macro == 'has_many' && (!assoc.options[:through]) ||
|
203
|
+
%w[references_many embeds_many].include?(macro)
|
143
204
|
assoc_type = 'one-many'
|
144
205
|
else # habtm or has_many, :through
|
145
|
-
|
206
|
+
# Add FAKE associations too in order to understand mistakes
|
207
|
+
return if @habtm.include? [assoc_class_name, class_name, assoc_name]
|
146
208
|
assoc_type = 'many-many'
|
147
|
-
@habtm << [class_name,
|
209
|
+
@habtm << [class_name, assoc_class_name, assoc_name]
|
148
210
|
end
|
149
211
|
# from patch #12384
|
150
212
|
# @graph.add_edge [assoc_type, class_name, assoc.class_name, assoc_name]
|
151
213
|
@graph.add_edge [assoc_type, class_name, assoc_class_name, assoc_name]
|
152
214
|
end # process_association
|
153
|
-
|
154
215
|
end # class ModelsDiagram
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: railroady
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 29
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 1.0.
|
9
|
+
- 5
|
10
|
+
version: 1.0.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Preston Lee
|
@@ -18,7 +18,7 @@ autorequire:
|
|
18
18
|
bindir: bin
|
19
19
|
cert_chain: []
|
20
20
|
|
21
|
-
date:
|
21
|
+
date: 2012-01-17 00:00:00 +05:30
|
22
22
|
default_executable: railroady
|
23
23
|
dependencies: []
|
24
24
|
|