activerecord_uml 0.10.0 → 0.14.0
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.
- checksums.yaml +4 -4
- data/README.md +19 -12
- data/exe/activerecord_relations +8 -0
- data/lib/activerecord_uml.rb +2 -26
- data/lib/activerecord_uml/activerecord_uml.rb +66 -0
- data/lib/activerecord_uml/class_drawer.rb +45 -0
- data/lib/activerecord_uml/relation.rb +24 -0
- data/lib/activerecord_uml/relation_drawer.rb +29 -0
- data/lib/activerecord_uml/version.rb +1 -1
- metadata +8 -3
- data/lib/activerecord_uml/diagram_drawer.rb +0 -64
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 50ec6f2cb089ba466d1fff00c4b69faf94d86a6760b7099e76afe0452c596b58
|
4
|
+
data.tar.gz: 6f79579599c6f8d19ac3a5cf3d438b746f6be552e2e76a3ca6224ada2a775df3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc65efc94125046d0c409ec50cbbaa2c5df6f9568309aad0b6dca01d2648d960df02fee6fb2c93cc2a5c4ece631b5714679b8db4cbd48331b9baab16e277d803
|
7
|
+
data.tar.gz: 055b92dd7b195376926167b7e9be35e074c9bf36cb342469ad8903a8846dcde2991168ad7e005354198dbe0a7f5ca1484c14e8417ebc6c216f51c79603551777
|
data/README.md
CHANGED
@@ -10,17 +10,7 @@ ActiverecordUml draws class diagrams of selected models to help to recognize the
|
|
10
10
|
|
11
11
|
## Installation
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
```ruby
|
16
|
-
gem 'activerecord_uml'
|
17
|
-
```
|
18
|
-
|
19
|
-
And then execute:
|
20
|
-
|
21
|
-
$ bundle install
|
22
|
-
|
23
|
-
Or install it yourself as:
|
13
|
+
install it yourself as:
|
24
14
|
|
25
15
|
$ gem install activerecord_uml
|
26
16
|
|
@@ -35,7 +25,13 @@ activerecord_uml User Book Review
|
|
35
25
|
Execute the activerecord_uml command with name of model classes.
|
36
26
|
Then the activerecord_uml outputs HTML text includes class diagrams of specified model classes.
|
37
27
|
|
38
|
-
For
|
28
|
+
For macOS, You can see the diagram:
|
29
|
+
```
|
30
|
+
activerecord_uml User Book Review > temp.html
|
31
|
+
open temp.html
|
32
|
+
```
|
33
|
+
|
34
|
+
I recommend to use the activerecord_uml with [browser](https://gist.github.com/defunkt/318247) command.
|
39
35
|
For example:
|
40
36
|
|
41
37
|
Install browser with Homebrew.
|
@@ -52,6 +48,17 @@ activerecord_uml User | browser
|
|
52
48
|
|
53
49
|
Open the class diagrams with the browser immediately.
|
54
50
|
|
51
|
+
### activerecord_relations
|
52
|
+
|
53
|
+
If you want to see the complex relationships between classes, you can use the activecord_relations command.
|
54
|
+
|
55
|
+
```
|
56
|
+
activerecord_relations User Book Review
|
57
|
+
```
|
58
|
+
|
59
|
+
This command will only show the relationships between the specified classes.
|
60
|
+
|
61
|
+
|
55
62
|
## Development
|
56
63
|
|
57
64
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake ` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -0,0 +1,8 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
|
3
|
+
activerecord_uml = File.join __dir__, "../lib/activerecord_uml"
|
4
|
+
ruby_script = "require \"#{activerecord_uml}\"; ActiverecordUml.draw"
|
5
|
+
rails = File.join Dir.pwd, "bin/rails"
|
6
|
+
rails_runner_command = "echo '#{ruby_script}' | #{rails} runner - --relation-only #{ARGV.join " "}"
|
7
|
+
|
8
|
+
system rails_runner_command
|
data/lib/activerecord_uml.rb
CHANGED
@@ -1,34 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require "erb"
|
3
3
|
require_relative "activerecord_uml/version"
|
4
|
-
require_relative "activerecord_uml/
|
4
|
+
require_relative "activerecord_uml/activerecord_uml"
|
5
5
|
|
6
6
|
module ActiverecordUml
|
7
7
|
def self.draw
|
8
|
-
|
9
|
-
<html>
|
10
|
-
<body>
|
11
|
-
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
12
|
-
<script>mermaid.initialize({startOnLoad:true});</script>
|
13
|
-
|
14
|
-
<div class="mermaid">
|
15
|
-
|
16
|
-
classDiagram
|
17
|
-
<% class_diagrams.each do |d| %>
|
18
|
-
<%= d %>
|
19
|
-
<% end %>
|
20
|
-
<% relations.each do |r| %>
|
21
|
-
<%= r %>
|
22
|
-
<% end %>
|
23
|
-
|
24
|
-
</div>
|
25
|
-
</body>
|
26
|
-
</html>
|
27
|
-
EOF
|
28
|
-
|
29
|
-
html_template = ERB.new html, nil, "<>"
|
30
|
-
classes = ARGV.map { |model_name| DiagramDrawer.new(model_name) }
|
31
|
-
puts html_template.result_with_hash class_diagrams: classes.map { |c| c.class_diagram },
|
32
|
-
relations: classes.map { |c| c.relations }.flatten.uniq
|
8
|
+
ActiverecordUml.new(ARGV).draw
|
33
9
|
end
|
34
10
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "erb"
|
3
|
+
require_relative "class_drawer"
|
4
|
+
require_relative "relation_drawer"
|
5
|
+
|
6
|
+
module ActiverecordUml
|
7
|
+
class ActiverecordUml
|
8
|
+
def initialize(args)
|
9
|
+
@args = args
|
10
|
+
end
|
11
|
+
|
12
|
+
def draw
|
13
|
+
puts html_template.result_with_hash classes: classes,
|
14
|
+
relations: relations
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def classes
|
20
|
+
options.include?(:relation_only) ? [] : target_classes.map { |klass| ClassDrawer.new(klass).diagram }
|
21
|
+
end
|
22
|
+
|
23
|
+
def relations
|
24
|
+
target_classes.map { |c| RelationDrawer.new(c).relations }
|
25
|
+
.flatten
|
26
|
+
.select { |r| options.include?(:relation_only) ? r.belongs_to?(target_classes.map(&:name)) : true }
|
27
|
+
.map(&:to_s)
|
28
|
+
.uniq
|
29
|
+
end
|
30
|
+
|
31
|
+
def target_classes
|
32
|
+
@args.select { |arg| !arg.start_with?("--") }
|
33
|
+
.map { |model_name| Object.const_get model_name }
|
34
|
+
end
|
35
|
+
|
36
|
+
def options
|
37
|
+
Set.new @args.select { |arg| arg.start_with?("--") }
|
38
|
+
.map { |arg| arg.gsub(/^--/, "").tr("-", "_").to_sym }
|
39
|
+
end
|
40
|
+
|
41
|
+
def html_template
|
42
|
+
html = <<EOF
|
43
|
+
<html>
|
44
|
+
<body>
|
45
|
+
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
|
46
|
+
<script>mermaid.initialize({startOnLoad:true});</script>
|
47
|
+
|
48
|
+
<div class="mermaid">
|
49
|
+
|
50
|
+
classDiagram
|
51
|
+
<% classes.each do |d| %>
|
52
|
+
<%= d %>
|
53
|
+
<% end %>
|
54
|
+
<% relations.each do |r| %>
|
55
|
+
<%= r %>
|
56
|
+
<% end %>
|
57
|
+
|
58
|
+
</div>
|
59
|
+
</body>
|
60
|
+
</html>
|
61
|
+
EOF
|
62
|
+
|
63
|
+
ERB.new html, nil, "<>"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require "erb"
|
2
|
+
|
3
|
+
module ActiverecordUml
|
4
|
+
class ClassDrawer
|
5
|
+
CLASS_TEMPLATE = <<EOF
|
6
|
+
class <%= klass.name %> {
|
7
|
+
<% klass.columns.each do |c| %>
|
8
|
+
<%= sprintf("%8s %s", c.type, c.name) %>
|
9
|
+
<% end %>
|
10
|
+
<% methods.each do |m, parameters| %>
|
11
|
+
<%= sprintf("%s(%s)", m, parameters) %>
|
12
|
+
<% end %>
|
13
|
+
}
|
14
|
+
EOF
|
15
|
+
|
16
|
+
def initialize(klass)
|
17
|
+
@klass = klass
|
18
|
+
end
|
19
|
+
|
20
|
+
def diagram
|
21
|
+
class_template.result_with_hash klass: @klass, methods: methods
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def class_template
|
27
|
+
ERB.new CLASS_TEMPLATE, nil, "<>"
|
28
|
+
end
|
29
|
+
|
30
|
+
def methods
|
31
|
+
@klass.public_instance_methods(false).sort.map do |m|
|
32
|
+
method_parameters = @klass.new.method(m)
|
33
|
+
.parameters
|
34
|
+
.filter { |a| a[0] == :req }
|
35
|
+
.map { |a| a[1] }
|
36
|
+
|
37
|
+
if method_parameters.length > 3
|
38
|
+
method_parameters = method_parameters.slice(0, 3).append("...")
|
39
|
+
end
|
40
|
+
|
41
|
+
[m.to_s, method_parameters.join(", ")]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module ActiverecordUml
|
2
|
+
class Relation
|
3
|
+
def initialize(left_name, multiplicity, right_name, association)
|
4
|
+
@left_name = left_name
|
5
|
+
@right_name = right_name
|
6
|
+
@association = association
|
7
|
+
@multiplicity = multiplicity
|
8
|
+
end
|
9
|
+
|
10
|
+
def belongs_to?(class_names)
|
11
|
+
class_names.include?(@left_name.to_s) && class_names.include?(@right_name)
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
"#{@left_name} #{@multiplicity} #{@right_name}#{label}"
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def label
|
21
|
+
@association.class_name != @association.name.to_s.classify ? " : #{@association.name.to_s.classify}" : ""
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "erb"
|
2
|
+
require_relative "./relation.rb"
|
3
|
+
|
4
|
+
module ActiverecordUml
|
5
|
+
class RelationDrawer
|
6
|
+
def initialize(klass)
|
7
|
+
@klass = klass
|
8
|
+
end
|
9
|
+
|
10
|
+
def relations
|
11
|
+
@klass.reflect_on_all_associations(:belongs_to).map do |a|
|
12
|
+
Relation.new(a.class_name, "--*", @klass, a)
|
13
|
+
end.concat(@klass.reflect_on_all_associations(:has_many).map do |a|
|
14
|
+
if a.is_a? ActiveRecord::Reflection::ThroughReflection
|
15
|
+
if a.source_reflection
|
16
|
+
# If a source association is specified, the class name of the source association is displayed.
|
17
|
+
Relation.new(@klass, "*--*", a.source_reflection.class_name, a)
|
18
|
+
else
|
19
|
+
Relation.new(@klass, "*--*", a.class_name, a)
|
20
|
+
end
|
21
|
+
else
|
22
|
+
Relation.new(@klass, "--*", a.class_name, a)
|
23
|
+
end
|
24
|
+
end).concat(@klass.reflect_on_all_associations(:has_one).map do |a|
|
25
|
+
Relation.new(@klass, "--*", a.class_name, a)
|
26
|
+
end)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
metadata
CHANGED
@@ -1,20 +1,21 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord_uml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- shigeru.nakajima
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-08-03 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Generate UML class diagram for Mermaid.js from ActiveRecord instances
|
14
14
|
by Rails runner.
|
15
15
|
email:
|
16
16
|
- shigeru.nakajima@gmail.com
|
17
17
|
executables:
|
18
|
+
- activerecord_relations
|
18
19
|
- activerecord_uml
|
19
20
|
extensions: []
|
20
21
|
extra_rdoc_files: []
|
@@ -26,9 +27,13 @@ files:
|
|
26
27
|
- activerecord_uml.gemspec
|
27
28
|
- bin/console
|
28
29
|
- bin/setup
|
30
|
+
- exe/activerecord_relations
|
29
31
|
- exe/activerecord_uml
|
30
32
|
- lib/activerecord_uml.rb
|
31
|
-
- lib/activerecord_uml/
|
33
|
+
- lib/activerecord_uml/activerecord_uml.rb
|
34
|
+
- lib/activerecord_uml/class_drawer.rb
|
35
|
+
- lib/activerecord_uml/relation.rb
|
36
|
+
- lib/activerecord_uml/relation_drawer.rb
|
32
37
|
- lib/activerecord_uml/version.rb
|
33
38
|
homepage: https://github.com/ledsun/activerecord_uml
|
34
39
|
licenses: []
|
@@ -1,64 +0,0 @@
|
|
1
|
-
require "erb"
|
2
|
-
|
3
|
-
module ActiverecordUml
|
4
|
-
class DiagramDrawer
|
5
|
-
CLASS_TEMPLATE = <<EOF
|
6
|
-
class <%= class_name %> {
|
7
|
-
<% class_name.columns.each do |c| %>
|
8
|
-
<%= sprintf("%8s %s", c.type, c.name) %>
|
9
|
-
<% end %>
|
10
|
-
<% methods.each do |m, parameters| %>
|
11
|
-
<%= sprintf("%s(%s)", m, parameters) %>
|
12
|
-
<% end %>
|
13
|
-
}
|
14
|
-
EOF
|
15
|
-
|
16
|
-
def initialize(model_name)
|
17
|
-
begin
|
18
|
-
@class_name = Object.const_get model_name
|
19
|
-
rescue NameError
|
20
|
-
STDERR.puts "#{model_name}というクラスがみつかりません"
|
21
|
-
raise
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def class_diagram
|
26
|
-
class_template.result_with_hash class_name: @class_name, methods: methods
|
27
|
-
end
|
28
|
-
|
29
|
-
def relations
|
30
|
-
@class_name.reflect_on_all_associations(:belongs_to).map do |a|
|
31
|
-
"#{a.class_name} --* #{@class_name}#{label_for a}"
|
32
|
-
end.concat(@class_name.reflect_on_all_associations(:has_many).map do |a|
|
33
|
-
"#{@class_name} --* #{a.class_name}#{label_for a}"
|
34
|
-
end).concat(@class_name.reflect_on_all_associations(:has_one).map do |a|
|
35
|
-
"#{@class_name} --* #{a.class_name}#{label_for a}"
|
36
|
-
end)
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
def class_template
|
42
|
-
ERB.new CLASS_TEMPLATE, nil, "<>"
|
43
|
-
end
|
44
|
-
|
45
|
-
def methods
|
46
|
-
@class_name.public_instance_methods(false).sort.map do |m|
|
47
|
-
method_parameters = @class_name.new.method(m)
|
48
|
-
.parameters
|
49
|
-
.filter { |a| a[0] == :req }
|
50
|
-
.map { |a| a[1] }
|
51
|
-
|
52
|
-
if method_parameters.length > 3
|
53
|
-
method_parameters = method_parameters.slice(0, 3).append("...")
|
54
|
-
end
|
55
|
-
|
56
|
-
[m.to_s, method_parameters.join(", ")]
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def label_for(association)
|
61
|
-
association.class_name != association.name.to_s.classify ? " : #{association.name.to_s.classify}" : ''
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|