rails-erd 1.4.7 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e10c973dc76bbb05773bc6920678cc060878c740
4
- data.tar.gz: 42af4a884c51e266b993d255a49e2647c2d4e368
3
+ metadata.gz: 624c7ed61b6bbe81a043bae64969f6bb1b6dd6f5
4
+ data.tar.gz: e3bf81680b796b264ac3d761d8ca8f13a0f4b9f9
5
5
  SHA512:
6
- metadata.gz: 9dbb498dd6dbfb15a243d3957e5172ab0fb6ffb54c39ba5ba4aac13ea7fb8a38d2272e07fd6b8b67651e39ed842620757b387c23cd77f4325d1736e3e5706efe
7
- data.tar.gz: ca3b2a15e3db16434341e6d8c2b439b0a97fcfd9ed0304b5eaf07d1e571b11d82ff44a0ffc6fbd352d0dbae8eb7c380b98beaef57d3ffe16ced26a7f4cbf4b81
6
+ metadata.gz: f4ec67e46803ac4c48801278c2f96e148c6f076d494ca0c16411f3a45f2fd517989ceacc42518315c22a34bb3e235ccfc4a841051d5022688f4f87897fe7b1fc
7
+ data.tar.gz: 9d7fdca071d98d557a0217659bee5a4550b6edb60a6850267050f9c591ae4b8eae2df3b787693cd78985aafd182f9b87a3de8f14262543596e037fd5c7f942e9
data/README.md CHANGED
@@ -6,7 +6,7 @@ Rails ERD - Generate Entity-Relationship Diagrams for Rails applications
6
6
 
7
7
  The second goal of Rails ERD is to provide you with a tool to inspect your application's domain model. If you don't like the default output, it is very easy to use the API to build your own diagrams.
8
8
 
9
- Rails ERD was created specifically for Rails and works on versions 3.0-4.2. It uses Active Record's built-in reflection capabilities to figure out how your models are associated.
9
+ Rails ERD was created specifically for Rails and works on versions 3.0-5.0. It uses Active Record's built-in reflection capabilities to figure out how your models are associated.
10
10
 
11
11
 
12
12
  Preview
@@ -60,7 +60,9 @@ warn: true
60
60
  title: sample title
61
61
  exclude: null
62
62
  only: null
63
+ only_recursion_depth: null
63
64
  prepend_primary: false
65
+ cluster: false
64
66
  ```
65
67
 
66
68
 
@@ -51,7 +51,9 @@ module RailsERD
51
51
  :title, true,
52
52
  :exclude, nil,
53
53
  :only, nil,
54
- :prepend_primary, false
54
+ :only_recursion_depth, nil,
55
+ :prepend_primary, false,
56
+ :cluster, false,
55
57
  ]
56
58
  end
57
59
  end
@@ -49,6 +49,11 @@ Choice.options do
49
49
  desc "Filter to only include listed models in diagram."
50
50
  end
51
51
 
52
+ option :only_recursion_depth do
53
+ long "--only_recursion_depth=INTEGER"
54
+ desc "Recurses into relations specified by --only upto a depth N."
55
+ end
56
+
52
57
  option :exclude do
53
58
  long "--exclude"
54
59
  desc "Filter to exclude listed models in diagram."
@@ -64,6 +69,11 @@ Choice.options do
64
69
  desc "Ensure primary key is at start of attribute list"
65
70
  end
66
71
 
72
+ option :cluster do
73
+ long "--cluster"
74
+ desc "Display models in subgraphs based on their namespace."
75
+ end
76
+
67
77
  separator ""
68
78
  separator "Output options:"
69
79
 
@@ -149,9 +159,14 @@ module RailsERD
149
159
 
150
160
  def load_application
151
161
  $stderr.puts "Loading application in '#{File.basename(path)}'..."
152
- # TODO: Add support for different kinds of environment.
153
- require "#{path}/config/environment"
154
- Rails.application.eager_load!
162
+ begin
163
+ environment_path = "#{path}/config/environment.rb"
164
+ require environment_path
165
+ rescue ::LoadError
166
+ puts "Please create a file in '#{environment_path}' that loads your application environment."
167
+ raise
168
+ end
169
+ Rails.application.eager_load! if defined? Rails
155
170
  rescue TypeError
156
171
  end
157
172
 
@@ -63,8 +63,10 @@ module RailsERD
63
63
  # [<string>]
64
64
  when :only, :exclude
65
65
  Array(value).join(",").split(",").map { |v| v.strip }
66
+
66
67
  # true | false
67
- when :disconnected, :indirect, :inheritance, :markup, :polymorphism, :warn
68
+ when :disconnected, :indirect, :inheritance, :markup, :polymorphism,
69
+ :warn, :cluster
68
70
  !!value
69
71
 
70
72
  # nil | <string>
@@ -125,6 +125,14 @@ module RailsERD
125
125
  def generate
126
126
  instance_eval(&callbacks[:setup])
127
127
 
128
+ if options.only_recursion_depth.present?
129
+ depth = options.only_recursion_depth.to_i
130
+ options.only.dup.each do |class_name|
131
+ options.only += recurse_into_relationships(@domain.entity_by_name(class_name), depth)
132
+ end
133
+ options.only.uniq!
134
+ end
135
+
128
136
  filtered_entities.each do |entity|
129
137
  instance_exec entity, filtered_attributes(entity), &callbacks[:each_entity]
130
138
  end
@@ -138,6 +146,26 @@ module RailsERD
138
146
  end
139
147
  end
140
148
 
149
+ def recurse_into_relationships(entity, max_level, current_level = 0)
150
+ return [] unless entity
151
+ return [] if max_level == current_level
152
+
153
+ relationships = entity.relationships.reject{|r| r.indirect? || r.recursive?}
154
+
155
+ relationships.map do |relationship|
156
+ other_entitiy = if relationship.source == entity
157
+ relationship.destination
158
+ else
159
+ relationship.source
160
+ end
161
+ if other_entitiy and !other_entitiy.generalized?
162
+ [other_entitiy.name] + recurse_into_relationships(other_entitiy, max_level, current_level + 1)
163
+ else
164
+ []
165
+ end
166
+ end.flatten.uniq
167
+ end
168
+
141
169
  def save
142
170
  instance_eval(&callbacks[:save])
143
171
  end
@@ -210,7 +210,14 @@ module RailsERD
210
210
  end
211
211
 
212
212
  each_entity do |entity, attributes|
213
- draw_node entity.name, entity_options(entity, attributes)
213
+ if options[:cluster] && entity.namespace
214
+ cluster_name = "cluster_#{entity.namespace}"
215
+ cluster = graph.get_graph(cluster_name) ||
216
+ graph.add_graph(cluster_name, label: entity.namespace)
217
+ draw_cluster_node cluster, entity.name, entity_options(entity, attributes)
218
+ else
219
+ draw_node entity.name, entity_options(entity, attributes)
220
+ end
214
221
  end
215
222
 
216
223
  each_specialization do |specialization|
@@ -233,15 +240,19 @@ module RailsERD
233
240
  private
234
241
 
235
242
  def node_exists?(name)
236
- !!graph.get_node(escape_name(name))
243
+ !!graph.search_node(escape_name(name))
237
244
  end
238
245
 
239
246
  def draw_node(name, options)
240
247
  graph.add_nodes escape_name(name), options
241
248
  end
242
249
 
250
+ def draw_cluster_node(cluster, name, options)
251
+ cluster.add_nodes escape_name(name), options
252
+ end
253
+
243
254
  def draw_edge(from, to, options)
244
- graph.add_edges graph.get_node(escape_name(from)), graph.get_node(escape_name(to)), options if node_exists?(from) and node_exists?(to)
255
+ graph.add_edges graph.search_node(escape_name(from)), graph.search_node(escape_name(to)), options if node_exists?(from) and node_exists?(to)
245
256
  end
246
257
 
247
258
  def escape_name(name)
@@ -92,6 +92,10 @@ module RailsERD
92
92
  @children ||= domain.specializations_by_entity_name(name).map(&:specialized)
93
93
  end
94
94
 
95
+ def namespace
96
+ name.scan(/(.*)::.*/).dig(0,0)
97
+ end
98
+
95
99
  def to_s # @private :nodoc:
96
100
  name
97
101
  end
@@ -30,7 +30,7 @@ module RailsERD
30
30
  end
31
31
 
32
32
  def abstract_from_models(domain, models)
33
- models.select(&:abstract_class?).collect(&:descendants).flatten.collect { |model|
33
+ models.select(&:abstract_class?).collect(&:direct_descendants).flatten.collect { |model|
34
34
  new(domain, domain.entity_by_name(model.superclass.name), domain.entity_by_name(model.name))
35
35
  }
36
36
  end
@@ -1,4 +1,4 @@
1
1
  module RailsERD
2
- VERSION = "1.4.7"
2
+ VERSION = "1.5.0"
3
3
  BANNER = "RailsERD #{VERSION}"
4
4
  end
@@ -146,6 +146,7 @@ class ActiveSupport::TestCase
146
146
  def reset_domain
147
147
  if defined? ActiveRecord
148
148
  ActiveRecord::Base.descendants.each do |model|
149
+ next if model.name == "ActiveRecord::InternalMetadata"
149
150
  model.reset_column_information
150
151
  Object.send :remove_const, model.name.to_sym if Object.const_defined? model.name.to_sym
151
152
  end
@@ -4,6 +4,7 @@ require File.expand_path("../test_helper", File.dirname(__FILE__))
4
4
  class AttributeTest < ActiveSupport::TestCase
5
5
  def with_native_limit(type, new_limit)
6
6
  ActiveRecord::Base.connection.class_eval do
7
+ undef :native_database_types
7
8
  define_method :native_database_types do
8
9
  super().tap do |types|
9
10
  types[type][:limit] = new_limit
@@ -13,6 +14,7 @@ class AttributeTest < ActiveSupport::TestCase
13
14
  yield
14
15
  ensure
15
16
  ActiveRecord::Base.connection.class_eval do
17
+ undef :native_database_types
16
18
  define_method :native_database_types do
17
19
  super()
18
20
  end
@@ -186,6 +186,15 @@ class DomainTest < ActiveSupport::TestCase
186
186
  assert_equal [Domain::Specialization] * 3, Domain.generate.specializations.collect(&:class)
187
187
  end
188
188
 
189
+ test "specializations should return specializations in domain model once for descendants of abstract class" do
190
+ create_model "Thing" do
191
+ self.abstract_class = true
192
+ end
193
+ create_model "Beverage", Thing, :type => :string
194
+ create_model "Beer", Beverage
195
+ assert_equal [Domain::Specialization], Domain.generate.specializations.collect(&:class)
196
+ end
197
+
189
198
  # Erroneous associations ===================================================
190
199
  test "relationships should omit bad has_many associations" do
191
200
  create_model "Foo" do
@@ -106,6 +106,7 @@ class GraphvizTest < ActiveSupport::TestCase
106
106
  begin
107
107
  GraphViz.class_eval do
108
108
  alias_method :old_output_and_errors_from_command, :output_and_errors_from_command
109
+ undef :output_and_errors_from_command
109
110
  def output_and_errors_from_command(*args); raise end
110
111
  end
111
112
  assert_nothing_raised do
@@ -113,6 +114,7 @@ class GraphvizTest < ActiveSupport::TestCase
113
114
  end
114
115
  ensure
115
116
  GraphViz.class_eval do
117
+ undef :output_and_errors_from_command
116
118
  alias_method :output_and_errors_from_command, :old_output_and_errors_from_command
117
119
  end
118
120
  end
@@ -137,7 +139,7 @@ class GraphvizTest < ActiveSupport::TestCase
137
139
 
138
140
  test "create should not create output if there are no connected models" do
139
141
  Diagram::Graphviz.create rescue nil
140
- assert !File.exists?("erd.png")
142
+ assert !File.exist?("erd.png")
141
143
  end
142
144
 
143
145
  test "create should abort and complain if there are no connected models" do
@@ -40,7 +40,7 @@ class RakeTaskTest < ActiveSupport::TestCase
40
40
 
41
41
  test "generate task should not create output if there are no connected models" do
42
42
  Rake::Task["erd:generate"].execute rescue nil
43
- assert !File.exists?("erd.dot")
43
+ assert !File.exist?("erd.dot")
44
44
  end
45
45
 
46
46
  test "generate task should eager load application environment" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-erd
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.7
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rolf Timmermans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-19 00:00:00.000000000 Z
11
+ date: 2016-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -133,7 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
133
133
  version: '0'
134
134
  requirements: []
135
135
  rubyforge_project:
136
- rubygems_version: 2.4.6
136
+ rubygems_version: 2.4.5.1
137
137
  signing_key:
138
138
  specification_version: 4
139
139
  summary: Entity-relationship diagram for your Rails models.