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 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
- gem 'railroady'
30
+ gem 'railroady'
31
31
  end
32
32
 
33
33
  ...and then run the master rake task...
data/VERSION.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
2
  :major: 1
3
3
  :minor: 0
4
- :patch: 4
4
+ :patch: 5
5
5
  :build:
@@ -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
- "#{ActiveRecord::Migrator.current_version}\\l" +
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
- #options.exclude.map! {|e| "app/models/" + e}
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.print "Generating models diagram\n" if @options.verbose
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.print "Warning: exception #{$!} raised while trying to load model class #{f}\n"
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
- STDERR.print "\tProcessing #{current_class}\n" if @options.verbose
44
-
45
- generated = false
46
-
47
- # Is current_clas derived from ActiveRecord::Base?
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
- # Not ActiveRecord::Base model
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
- @graph.add_node ['module', current_class.name]
49
+ process_basic_module(current_class)
104
50
  end
105
51
 
106
- # Only consider meaningful inheritance relations for generated classes
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
- return if assoc.macro.to_s == 'belongs_to' && !@options.show_belongs_to
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 ['has_one', 'belongs_to'].include? assoc.macro.to_s
200
+ if %w[has_one references_one embeds_one].include?(macro)
141
201
  assoc_type = 'one-one'
142
- elsif assoc.macro.to_s == 'has_many' && (! assoc.options[:through])
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
- return if @habtm.include? [assoc.class_name, class_name, assoc_name]
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, assoc.class_name, assoc_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: 31
4
+ hash: 29
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 4
10
- version: 1.0.4
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: 2011-12-30 00:00:00 +05:30
21
+ date: 2012-01-17 00:00:00 +05:30
22
22
  default_executable: railroady
23
23
  dependencies: []
24
24