jw-rails-erd 1.4.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.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +86 -0
  3. data/Rakefile +20 -0
  4. data/bin/erd +4 -0
  5. data/lib/generators/erd/USAGE +4 -0
  6. data/lib/generators/erd/install_generator.rb +14 -0
  7. data/lib/generators/erd/templates/auto_generate_diagram.rake +6 -0
  8. data/lib/rails-erd.rb +1 -0
  9. data/lib/rails_erd/cli.rb +164 -0
  10. data/lib/rails_erd/config.rb +97 -0
  11. data/lib/rails_erd/custom.rb +99 -0
  12. data/lib/rails_erd/diagram/graphviz.rb +295 -0
  13. data/lib/rails_erd/diagram/templates/node.html.erb +14 -0
  14. data/lib/rails_erd/diagram/templates/node.record.erb +4 -0
  15. data/lib/rails_erd/diagram.rb +188 -0
  16. data/lib/rails_erd/domain/attribute.rb +160 -0
  17. data/lib/rails_erd/domain/entity.rb +104 -0
  18. data/lib/rails_erd/domain/relationship/cardinality.rb +118 -0
  19. data/lib/rails_erd/domain/relationship.rb +203 -0
  20. data/lib/rails_erd/domain/specialization.rb +90 -0
  21. data/lib/rails_erd/domain.rb +153 -0
  22. data/lib/rails_erd/railtie.rb +10 -0
  23. data/lib/rails_erd/tasks.rake +58 -0
  24. data/lib/rails_erd/version.rb +4 -0
  25. data/lib/rails_erd.rb +73 -0
  26. data/lib/tasks/auto_generate_diagram.rake +21 -0
  27. data/test/support_files/erdconfig.another_example +3 -0
  28. data/test/support_files/erdconfig.example +19 -0
  29. data/test/support_files/erdconfig.exclude.example +19 -0
  30. data/test/test_helper.rb +160 -0
  31. data/test/unit/attribute_test.rb +316 -0
  32. data/test/unit/cardinality_test.rb +123 -0
  33. data/test/unit/config_test.rb +110 -0
  34. data/test/unit/diagram_test.rb +352 -0
  35. data/test/unit/domain_test.rb +258 -0
  36. data/test/unit/entity_test.rb +252 -0
  37. data/test/unit/graphviz_test.rb +461 -0
  38. data/test/unit/rake_task_test.rb +174 -0
  39. data/test/unit/relationship_test.rb +476 -0
  40. data/test/unit/specialization_test.rb +67 -0
  41. metadata +155 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 479e99642119a6eb335c9b9c97eed2e0e59ebf86
4
+ data.tar.gz: a3593fb95a3f2d816660964734e20356921917c1
5
+ SHA512:
6
+ metadata.gz: 2460431f9ec8fc7daa093b4ecb86e12bea5a7ab471e6db8e309b2c3ecf37f1f9c9acfe87ec2c66e88b7780c0d5701cfeaddaf10e1b54a3221d80d3025ada50ef
7
+ data.tar.gz: ef125a202ce97ba684ddea1b4344656d54f025a45e857d24e97c35ba42373b4d810bbb4327b58805ffbd04a19b7a0d7780f51b340be9f1847fbaf5754fd5c8bc
data/README.md ADDED
@@ -0,0 +1,86 @@
1
+ Rails ERD - Generate Entity-Relationship Diagrams for Rails applications
2
+ ========================================================================
3
+ [![Build Status](https://travis-ci.org/voormedia/rails-erd.svg?branch=master)](https://travis-ci.org/voormedia/rails-erd) [![Code Climate](https://codeclimate.com/github/voormedia/rails-erd/badges/gpa.svg)](https://codeclimate.com/github/voormedia/rails-erd)
4
+
5
+ [Rails ERD](http://voormedia.github.io/rails-erd/) is a gem that allows you to easily generate a diagram based on your application's Active Record models. The diagram gives an overview of how your models are related. Having a diagram that describes your models is perfect documentation for your application.
6
+
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
+
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.
10
+
11
+
12
+ Preview
13
+ -------
14
+
15
+ Here's an example entity-relationship diagram that was generated by Rails ERD:
16
+
17
+ ![Entity-Relationship Diagram](http://voormedia.github.io/rails-erd/images/entity-relationship-diagram.png)
18
+
19
+ Browse the [gallery](http://voormedia.github.io/rails-erd/gallery.html) for more example diagrams.
20
+
21
+
22
+ Requirements
23
+ ---------------
24
+
25
+ * Ruby 1.9.3+
26
+ * ActiveRecord 3.x
27
+
28
+ Getting started
29
+ ---------------
30
+
31
+ See the [installation instructions](http://voormedia.github.io/rails-erd/install.html) for a complete description of how to install Rails ERD. Here's a summary:
32
+
33
+ * Install Graphviz 2.22+ ([how?](http://voormedia.github.io/rails-erd/install.html))
34
+
35
+ * Add <tt>gem "rails-erd"</tt> to your application's Gemfile
36
+
37
+ * Run <tt>bundle exec erd</tt>
38
+
39
+ ### Configuration
40
+
41
+
42
+ Rails ERD has the ability to be configured via the command line or through the use of a YAML file with configuration options set. It will look for this file first at `~/.erdconfig` and then `./.erdconfig` (which will override any settings in `~/.erdconfig`). The format of the file is as follows (shown here with the default settings used if no `.erdconfig` is found). More information on [customization options](http://voormedia.github.io/rails-erd/customise.html) can be found in Rails ERD's project documentation.
43
+
44
+ ```
45
+ attributes:
46
+ - content
47
+ - foreign_key
48
+ - inheritance
49
+ disconnected: true
50
+ filename: erd
51
+ filetype: pdf
52
+ indirect: true
53
+ inheritance: false
54
+ markup: true
55
+ notation: simple
56
+ orientation: horizontal
57
+ polymorphism: false
58
+ sort: true
59
+ warn: true
60
+ title: sample title
61
+ exclude: null
62
+ only: null
63
+ prepend_primary: false
64
+ ```
65
+
66
+
67
+ Learn more
68
+ ----------
69
+
70
+ More information can be found on [Rails ERD's project homepage](http://voormedia.github.io/rails-erd/).
71
+
72
+ If you wish to extend or customise Rails ERD, take a look at the [API documentation](http://rubydoc.info/github/voormedia/rails-erd/frames).
73
+
74
+
75
+ About Rails ERD
76
+ ---------------
77
+
78
+ Rails ERD was created by Rolf Timmermans (r.timmermans *at* voormedia.com)
79
+
80
+ Copyright 2010-2015 Voormedia - [www.voormedia.com](http://www.voormedia.com/)
81
+
82
+
83
+ License
84
+ -------
85
+
86
+ Rails ERD is released under the MIT license.
data/Rakefile ADDED
@@ -0,0 +1,20 @@
1
+ require "bundler"
2
+ require "rake/testtask"
3
+ require "yard"
4
+
5
+ Bundler::GemHelper.install_tasks
6
+
7
+ Rake::TestTask.new do |test|
8
+ test.test_files = FileList["test/**/*_test.rb"]
9
+ end
10
+
11
+ YARD::Rake::YardocTask.new do |yard|
12
+ yard.files = ["lib/**/*.rb", "-", "LICENSE", "CHANGES.md"]
13
+ end
14
+
15
+ desc "Generate diagrams for bundled examples"
16
+ task :examples do
17
+ require File.expand_path("examples/generate", File.dirname(__FILE__))
18
+ end
19
+
20
+ task :default => :test
data/bin/erd ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require "rails_erd/cli"
3
+
4
+ RailsERD::CLI.start
@@ -0,0 +1,4 @@
1
+ Add a .rake file that automatically generate the graphical models when you do
2
+ a db:migrate in development mode:
3
+
4
+ rails generate erd:install
@@ -0,0 +1,14 @@
1
+ module Erd
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ desc "Copy rails-erd rakefiles for automatic graphic generation"
5
+ source_root File.expand_path('../templates', __FILE__)
6
+
7
+ # copy rake tasks
8
+ def copy_tasks
9
+ template "auto_generate_diagram.rake", "lib/tasks/auto_generate_diagram.rake"
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,6 @@
1
+ # NOTE: only doing this in development as some production environments (Heroku)
2
+ # NOTE: are sensitive to local FS writes, and besides -- it's just not proper
3
+ # NOTE: to have a dev-mode tool do its thing in production.
4
+ if Rails.env.development?
5
+ Erd.load_tasks
6
+ end
data/lib/rails-erd.rb ADDED
@@ -0,0 +1 @@
1
+ require "rails_erd"
@@ -0,0 +1,164 @@
1
+ require "choice"
2
+
3
+ Choice.options do
4
+ separator ""
5
+ separator "Diagram options:"
6
+
7
+ option :title do
8
+ long "--title=TITLE"
9
+ desc "Replace default diagram title with a custom one."
10
+ end
11
+
12
+ option :notation do
13
+ long "--notation=STYLE"
14
+ desc "Diagram notation style, one of simple, bachman, uml or crowsfoot."
15
+ end
16
+
17
+ option :attributes do
18
+ long "--attributes=TYPE,..."
19
+ desc "Attribute groups to display: false, content, primary_keys, foreign_keys, timestamps and/or inheritance."
20
+ end
21
+
22
+ option :orientation do
23
+ long "--orientation=ORIENTATION"
24
+ desc "Orientation of diagram, either horizontal (default) or vertical."
25
+ end
26
+
27
+ option :inheritance do
28
+ long "--inheritance"
29
+ desc "Display (single table) inheritance relationships."
30
+ end
31
+
32
+ option :polymorphism do
33
+ long "--polymorphism"
34
+ desc "Display polymorphic and abstract entities."
35
+ end
36
+
37
+ option :no_indirect do
38
+ long "--direct"
39
+ desc "Omit indirect relationships (through other entities)."
40
+ end
41
+
42
+ option :no_disconnected do
43
+ long "--connected"
44
+ desc "Omit entities without relationships."
45
+ end
46
+
47
+ option :only do
48
+ long "--only"
49
+ desc "Filter to only include listed models in diagram."
50
+ end
51
+
52
+ option :exclude do
53
+ long "--exclude"
54
+ desc "Filter to exclude listed models in diagram."
55
+ end
56
+
57
+ option :sort do
58
+ long "--sort=BOOLEAN"
59
+ desc "Sort attribute list alphabetically"
60
+ end
61
+
62
+ option :prepend_primary do
63
+ long "--prepend_primary=BOOLEAN"
64
+ desc "Ensure primary key is at start of attribute list"
65
+ end
66
+
67
+ separator ""
68
+ separator "Output options:"
69
+
70
+ option :filename do
71
+ long "--filename=FILENAME"
72
+ desc "Basename of the output diagram."
73
+ end
74
+
75
+ option :filetype do
76
+ long "--filetype=TYPE"
77
+ desc "Output file type. Available types depend on the diagram renderer."
78
+ end
79
+
80
+ option :no_markup do
81
+ long "--no-markup"
82
+ desc "Disable markup for enhanced compatibility of .dot output with other applications."
83
+ end
84
+
85
+ option :open do
86
+ long "--open"
87
+ desc "Open the output file after it has been saved."
88
+ end
89
+
90
+ separator ""
91
+ separator "Common options:"
92
+
93
+ option :help do
94
+ long "--help"
95
+ desc "Display this help message."
96
+ end
97
+
98
+ option :debug do
99
+ long "--debug"
100
+ desc "Show stack traces when an error occurs."
101
+ end
102
+
103
+ option :version do
104
+ short "-v"
105
+ long "--version"
106
+ desc "Show version and quit."
107
+ action do
108
+ require "rails_erd/version"
109
+ $stderr.puts RailsERD::BANNER
110
+ exit
111
+ end
112
+ end
113
+ end
114
+
115
+ module RailsERD
116
+ class CLI
117
+ attr_reader :path, :options
118
+
119
+ class << self
120
+ def start
121
+ path = Choice.rest.first || Dir.pwd
122
+ options = Choice.choices.each_with_object({}) do |(key, value), opts|
123
+ if key.start_with? "no_"
124
+ opts[key.gsub("no_", "").to_sym] = !value
125
+ elsif value.to_s.include? ","
126
+ opts[key.to_sym] = value.split(",").map(&:to_s)
127
+ else
128
+ opts[key.to_sym] = value
129
+ end
130
+ end
131
+ new(path, options).start
132
+ end
133
+ end
134
+
135
+ def initialize(path, options)
136
+ @path, @options = path, options
137
+ require "rails_erd/diagram/graphviz"
138
+ end
139
+
140
+ def start
141
+ load_application
142
+ create_diagram
143
+ rescue Exception => e
144
+ $stderr.puts "Failed: #{e.class}: #{e.message}"
145
+ $stderr.puts e.backtrace.map { |t| " from #{t}" } if options[:debug]
146
+ end
147
+
148
+ private
149
+
150
+ def load_application
151
+ $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!
155
+ end
156
+
157
+ def create_diagram
158
+ $stderr.puts "Generating entity-relationship diagram for #{ActiveRecord::Base.descendants.length} models..."
159
+ file = RailsERD::Diagram::Graphviz.create(options)
160
+ $stderr.puts "Diagram saved to '#{file}'."
161
+ `open #{file}` if options[:open]
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,97 @@
1
+ require "yaml"
2
+
3
+ module RailsERD
4
+ class Config
5
+ USER_WIDE_CONFIG_FILE = File.expand_path(".erdconfig", ENV["HOME"])
6
+ CURRENT_CONFIG_FILE = File.expand_path(".erdconfig", Dir.pwd)
7
+
8
+ attr_reader :options
9
+
10
+ def self.load
11
+ new.load
12
+ end
13
+
14
+ def initialize
15
+ @options = {}
16
+ end
17
+
18
+ def load
19
+ load_file(USER_WIDE_CONFIG_FILE)
20
+ load_file(CURRENT_CONFIG_FILE)
21
+
22
+ @options
23
+ end
24
+
25
+ def self.font_names_based_on_os
26
+ if use_os_x_fonts?
27
+ { normal: "ArialMT",
28
+ bold: "Arial BoldMT",
29
+ italic: "Arial ItalicMT" }
30
+ else
31
+ { normal: "Arial",
32
+ bold: "Arial Bold",
33
+ italic: "Arial Italic" }
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def load_file(path)
40
+ if File.exists?(path)
41
+ YAML.load_file(path).each do |key, value|
42
+ key = key.to_sym
43
+ @options[key] = normalize_value(key, value)
44
+ end
45
+ end
46
+ end
47
+
48
+ def normalize_value(key, value)
49
+ case key
50
+ # <symbol>[,<symbol>,...] | false
51
+ when :attributes
52
+ if value == false
53
+ return value
54
+ else
55
+ # Comma separated string and strings in array are OK.
56
+ Array(value).join(",").split(",").map { |v| v.strip.to_sym }
57
+ end
58
+
59
+ # <symbol>
60
+ when :filetype, :notation, :orientation
61
+ value.to_sym
62
+
63
+ # [<string>]
64
+ when :only, :exclude
65
+ Array(value).join(",").split(",").map { |v| v.strip }
66
+ # true | false
67
+ when :disconnected, :indirect, :inheritance, :markup, :polymorphism, :warn
68
+ !!value
69
+
70
+ # nil | <string>
71
+ when :filename
72
+ value.nil? ? nil : value.to_s
73
+
74
+ # true | false | <string>
75
+ when :title
76
+ value.is_a?(String) ? value : !!value
77
+
78
+ else
79
+ value
80
+ end
81
+ end
82
+
83
+ def self.use_os_x_fonts?
84
+ host = RbConfig::CONFIG['host_os']
85
+ return true if host == "darwin"
86
+
87
+ if host.include? "darwin"
88
+ darwin_version_array = host.split("darwin").last.split(".").map(&:to_i)
89
+
90
+ return true if darwin_version_array[0] >= 13
91
+ return true if darwin_version_array[0] == 12 && darwin_version_array[1] >= 5
92
+ end
93
+
94
+ false
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,99 @@
1
+ require "rails_erd/domain"
2
+ require "rails_erd/domain"
3
+ require "rails_erd"
4
+ require "rails_erd/domain/attribute"
5
+ require "rails_erd/domain/entity"
6
+ require "rails_erd/domain/relationship"
7
+ require "rails_erd/domain/specialization"
8
+
9
+
10
+
11
+ # monkeypatch to fix strange people with edges which causes segfault in graphviz
12
+ # https://github.com/voormedia/rails-erd/issues/70
13
+ module RailsERD
14
+ class Domain
15
+ class Relationship
16
+ class << self
17
+ private
18
+
19
+ def association_identity(association)
20
+ Set[association_owner(association), association_target(association)]
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+
28
+ module RailsERD
29
+ class Custom
30
+ attr_accessor :classes, :reflection_keys
31
+
32
+ #@class_name - Pass in the class name
33
+ #@name of the file
34
+ #@level - the depth you want to browse
35
+ def initialize( class_name, file_name, level=nil )
36
+
37
+ @file_name = file_name
38
+ @class_name = class_name
39
+ @classes = []
40
+ @classes << class_name
41
+ @level = level
42
+ process
43
+ generate
44
+
45
+ end
46
+
47
+ def generate
48
+ puts "************************ classes length: #{@classes.length}"
49
+ options = {
50
+ :filename=>@file_name,
51
+ :filetype=>"pdf",
52
+ :attributes=>["foreign_keys", "primary_keys", "content"],
53
+ :only=>@classes
54
+ }
55
+ begin
56
+ byebug
57
+ file = RailsERD::Diagram::Graphviz.create(options)
58
+ rescue
59
+ puts "---------------------------------Graph viz creation error"
60
+ end
61
+ end
62
+ def process
63
+ children_walk( @class_name.constantize.reflections, 0 )
64
+ end
65
+
66
+
67
+ def children_walk( reflections, cur_level )
68
+ if @level == cur_level
69
+ return
70
+ end
71
+ keys = reflections.keys
72
+ for k in keys
73
+ p "***processing: #{k}"
74
+ ref = reflections[ k ]
75
+ class_name = ref.klass.name.to_s
76
+ p class_name
77
+ if !@classes.include? class_name
78
+
79
+ p "Adding #{class_name}"
80
+ @classes << class_name
81
+
82
+ begin
83
+ model = class_name.constantize
84
+ children_walk( model.reflections, cur_level + 1 )
85
+ rescue => e
86
+ warn "Cannot retrieve model: #{class_name}"
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ def check_model_validity(model)
93
+ model.abstract_class? or model.table_exists? or raise "table #{model.table_name} does not exist"
94
+ rescue => e
95
+ warn "Ignoring invalid model #{model.name} (#{e.message})"
96
+ end
97
+
98
+ end
99
+ end