jw-rails-erd 1.4.5

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