railroady 1.0.4 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
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