rails-mermaid_erd_markdown 0.2.0 → 0.3.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/.github/CODEOWNERS.md +1 -0
- data/.github/workflows/CI.yml +42 -0
- data/.github/workflows/codeql.yml +93 -0
- data/.rubocop.yml +30 -6
- data/.ruby-version +1 -0
- data/Gemfile +6 -9
- data/Gemfile.lock +77 -69
- data/README.md +36 -9
- data/Rakefile +1 -1
- data/bin/console +1 -1
- data/bin/rubocop +29 -0
- data/docs/examples/erd.yml +1 -1
- data/lib/rails-mermaid_erd_markdown/configuration.rb +11 -3
- data/lib/rails-mermaid_erd_markdown/generator.rb +169 -0
- data/lib/rails-mermaid_erd_markdown/markdown_document.rb +104 -0
- data/lib/rails-mermaid_erd_markdown/source_data.rb +63 -0
- data/lib/rails-mermaid_erd_markdown/version.rb +1 -1
- data/lib/rails-mermaid_erd_markdown.rb +3 -93
- data/rails-mermaid_erd_markdown.gemspec +5 -3
- data/test/example_output/mock_ERD.md +48 -0
- data/test/example_output/mock_ERD_index.md +10 -0
- data/test/example_output/mock_ERD_model.md +46 -0
- data/test/mock_data/models.rb +105 -0
- data/test/test_helper.rb +4 -2
- data/test/test_rails/rails-mermaid_erd_markdown/test_generator.rb +54 -0
- data/test/test_rails/rails-mermaid_erd_markdown/test_markdown_document.rb +76 -0
- data/test/test_rails/rails-mermaid_erd_markdown/test_source_data.rb +70 -0
- data/test/test_rails/test_rails-mermaid_erd_markdown.rb +0 -40
- metadata +19 -63
- data/test/dummy-rails/.dockerignore +0 -37
- data/test/dummy-rails/.ruby-version +0 -1
- data/test/dummy-rails/Rakefile +0 -6
- data/test/dummy-rails/app/assets/config/manifest.js +0 -4
- data/test/dummy-rails/app/assets/images/.keep +0 -0
- data/test/dummy-rails/app/assets/stylesheets/application.css +0 -15
- data/test/dummy-rails/app/channels/application_cable/channel.rb +0 -4
- data/test/dummy-rails/app/channels/application_cable/connection.rb +0 -4
- data/test/dummy-rails/app/controllers/application_controller.rb +0 -2
- data/test/dummy-rails/app/controllers/concerns/.keep +0 -0
- data/test/dummy-rails/app/helpers/application_helper.rb +0 -2
- data/test/dummy-rails/app/javascript/application.js +0 -3
- data/test/dummy-rails/app/javascript/controllers/application.js +0 -9
- data/test/dummy-rails/app/javascript/controllers/hello_controller.js +0 -7
- data/test/dummy-rails/app/javascript/controllers/index.js +0 -11
- data/test/dummy-rails/app/jobs/application_job.rb +0 -7
- data/test/dummy-rails/app/mailers/application_mailer.rb +0 -4
- data/test/dummy-rails/app/models/application_record.rb +0 -3
- data/test/dummy-rails/app/models/concerns/.keep +0 -0
- data/test/dummy-rails/app/views/layouts/application.html.erb +0 -16
- data/test/dummy-rails/app/views/layouts/mailer.html.erb +0 -13
- data/test/dummy-rails/app/views/layouts/mailer.text.erb +0 -1
- data/test/dummy-rails/bin/bundle +0 -114
- data/test/dummy-rails/bin/docker-entrypoint +0 -8
- data/test/dummy-rails/bin/importmap +0 -4
- data/test/dummy-rails/bin/rails +0 -4
- data/test/dummy-rails/bin/rake +0 -4
- data/test/dummy-rails/bin/setup +0 -33
- data/test/dummy-rails/config/application.rb +0 -27
- data/test/dummy-rails/config/boot.rb +0 -3
- data/test/dummy-rails/config/cable.yml +0 -10
- data/test/dummy-rails/config/credentials.yml.enc +0 -1
- data/test/dummy-rails/config/database.yml +0 -25
- data/test/dummy-rails/config/environment.rb +0 -5
- data/test/dummy-rails/config/environments/development.rb +0 -76
- data/test/dummy-rails/config/environments/production.rb +0 -97
- data/test/dummy-rails/config/environments/test.rb +0 -64
- data/test/dummy-rails/config/importmap.rb +0 -7
- data/test/dummy-rails/config/initializers/content_security_policy.rb +0 -25
- data/test/dummy-rails/config/initializers/filter_parameter_logging.rb +0 -8
- data/test/dummy-rails/config/initializers/inflections.rb +0 -16
- data/test/dummy-rails/config/initializers/permissions_policy.rb +0 -13
- data/test/dummy-rails/config/locales/en.yml +0 -31
- data/test/dummy-rails/config/puma.rb +0 -35
- data/test/dummy-rails/config/routes.rb +0 -10
- data/test/dummy-rails/config/storage.yml +0 -34
- data/test/dummy-rails/config.ru +0 -6
- data/test/dummy-rails/db/seeds.rb +0 -9
- data/test/dummy-rails/test/application_system_test_case.rb +0 -5
- data/test/dummy-rails/test/channels/application_cable/connection_test.rb +0 -13
- data/test/dummy-rails/test/controllers/.keep +0 -0
- data/test/dummy-rails/test/fixtures/files/.keep +0 -0
- data/test/dummy-rails/test/helpers/.keep +0 -0
- data/test/dummy-rails/test/integration/.keep +0 -0
- data/test/dummy-rails/test/mailers/.keep +0 -0
- data/test/dummy-rails/test/models/.keep +0 -0
- data/test/dummy-rails/test/system/.keep +0 -0
- data/test/dummy-rails/test/test_helper.rb +0 -15
- data/test/dummy-rails/vendor/.keep +0 -0
- data/test/dummy-rails/vendor/javascript/.keep +0 -0
- data/test/util/mock_ERD.md +0 -27
@@ -0,0 +1,169 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "configuration"
|
4
|
+
require_relative "markdown_document"
|
5
|
+
require_relative "source_data"
|
6
|
+
require "digest/md5"
|
7
|
+
require "logger"
|
8
|
+
require "pathname"
|
9
|
+
|
10
|
+
module MermaidErdMarkdown
|
11
|
+
class Generator
|
12
|
+
attr_writer :logger
|
13
|
+
|
14
|
+
def self.generate
|
15
|
+
new.generate
|
16
|
+
end
|
17
|
+
|
18
|
+
def generate
|
19
|
+
return unless find_or_create_output
|
20
|
+
return unless erd_changed?
|
21
|
+
|
22
|
+
update_erd
|
23
|
+
|
24
|
+
update_split_erds if configuration.split_output
|
25
|
+
end
|
26
|
+
|
27
|
+
def index_markdown(files)
|
28
|
+
MermaidErdMarkdown::MarkdownDocument.create do |doc|
|
29
|
+
doc.add(doc.header("Entity Relationship Diagrams"))
|
30
|
+
doc.add(
|
31
|
+
"Each model has its own ERD diagram. The diagram shows the " \
|
32
|
+
"selected model, plus #{configuration.relationship_depth} " \
|
33
|
+
"associated model(s) deep. Click on the model name to view " \
|
34
|
+
"the diagram.\n"
|
35
|
+
)
|
36
|
+
doc.add(doc.subheader("Models"))
|
37
|
+
files.each do |model, path|
|
38
|
+
doc.add(doc.list_item(doc.link(model, "../#{path}")))
|
39
|
+
end
|
40
|
+
doc.add("")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def model_markdown(output)
|
45
|
+
MermaidErdMarkdown::MarkdownDocument.create do |doc|
|
46
|
+
model_name = output[:Models].first[:ModelName]
|
47
|
+
doc.add(doc.header("#{model_name} Entity-Relationship Diagram"))
|
48
|
+
doc.add(doc.subheader("Associated Models"))
|
49
|
+
output[:Models].each do |model|
|
50
|
+
next if model[:ModelName] == model_name
|
51
|
+
|
52
|
+
model_path = "../#{output_path(model[:ModelName])}"
|
53
|
+
|
54
|
+
doc.add(doc.list_item(doc.link(model[:ModelName], model_path)))
|
55
|
+
end
|
56
|
+
doc.add("")
|
57
|
+
doc.add(doc.subheader("Entity-Relationship Diagram"))
|
58
|
+
doc.add(mermaid_markdown(output))
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def mermaid_markdown(source)
|
63
|
+
MermaidErdMarkdown::MarkdownDocument.create do
|
64
|
+
erd do
|
65
|
+
add(
|
66
|
+
source[:Models].map do |model|
|
67
|
+
erd_table(model[:TableName], model[:ModelName]) do
|
68
|
+
model[:Columns].map do |column|
|
69
|
+
erd_table_column(column)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
)
|
74
|
+
add(
|
75
|
+
source[:Relations].map do |relation|
|
76
|
+
erd_relation(relation)
|
77
|
+
end
|
78
|
+
)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def comprehensive_erd
|
86
|
+
@comprehensive_erd ||= mermaid_markdown(source_data.data)
|
87
|
+
end
|
88
|
+
|
89
|
+
def configuration
|
90
|
+
@configuration ||= MermaidErdMarkdown::Configuration.new
|
91
|
+
end
|
92
|
+
|
93
|
+
def erd_changed?
|
94
|
+
# check if two diagrams are the same by comparing their MD5 hashes
|
95
|
+
existing_erd_hash = Digest::MD5.hexdigest(File.read(output_path))
|
96
|
+
new_erd_hash = Digest::MD5.hexdigest(comprehensive_erd)
|
97
|
+
|
98
|
+
return true if existing_erd_hash != new_erd_hash
|
99
|
+
|
100
|
+
logger.info("ERD already exists and is up to date. Skipping...")
|
101
|
+
|
102
|
+
false
|
103
|
+
end
|
104
|
+
|
105
|
+
def find_or_create_output
|
106
|
+
return true if output_path.exist?
|
107
|
+
|
108
|
+
logger.info("ERD does not currently exist at result path. Creating...")
|
109
|
+
begin
|
110
|
+
write_file("", output_path)
|
111
|
+
logger.info("ERD successfully created at #{output_path}")
|
112
|
+
rescue StandardError
|
113
|
+
logger.info("Could not create ERD. Output path is invalid.")
|
114
|
+
|
115
|
+
false
|
116
|
+
end
|
117
|
+
|
118
|
+
true
|
119
|
+
end
|
120
|
+
|
121
|
+
def logger
|
122
|
+
@logger ||= Logger.new($stdout).tap do |log|
|
123
|
+
log.progname = self.class.name.split("::").first
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def output_path(extension = nil)
|
128
|
+
return Pathname.new(configuration.output_path) unless extension
|
129
|
+
|
130
|
+
Pathname.new(configuration.output_path).sub_ext("_#{extension}.md")
|
131
|
+
end
|
132
|
+
|
133
|
+
def source_data
|
134
|
+
@source_data ||= MermaidErdMarkdown::SourceData.new
|
135
|
+
end
|
136
|
+
|
137
|
+
def update_erd
|
138
|
+
logger.info("ERD writing to #{output_path}...")
|
139
|
+
write_file(comprehensive_erd, output_path)
|
140
|
+
logger.info("ERD successfully written")
|
141
|
+
end
|
142
|
+
|
143
|
+
def update_split_erds
|
144
|
+
# first remove all existing model ERD files
|
145
|
+
Dir.glob(output_path.sub_ext("_*.md")).each do |file|
|
146
|
+
File.delete(file)
|
147
|
+
end
|
148
|
+
|
149
|
+
files = {}
|
150
|
+
|
151
|
+
depth = configuration.relationship_depth
|
152
|
+
|
153
|
+
source_data.split_output(depth).each do |output|
|
154
|
+
model_name = output[:Models].first[:ModelName]
|
155
|
+
model_path = output_path(model_name)
|
156
|
+
write_file(model_markdown(output), model_path)
|
157
|
+
logger.info("ERD successfully written to #{model_path}")
|
158
|
+
files[model_name] = model_path
|
159
|
+
end
|
160
|
+
|
161
|
+
index_path = output_path("index")
|
162
|
+
write_file(index_markdown(files), index_path)
|
163
|
+
end
|
164
|
+
|
165
|
+
def write_file(new_erd, path)
|
166
|
+
File.write(path, new_erd)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MermaidErdMarkdown
|
4
|
+
class MarkdownDocument
|
5
|
+
attr_accessor :is_show_key, :is_show_comment
|
6
|
+
|
7
|
+
def self.create(&block)
|
8
|
+
new.generate(&block)
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@is_show_key = true
|
13
|
+
@is_show_comment = true
|
14
|
+
end
|
15
|
+
|
16
|
+
def add(element)
|
17
|
+
document << element
|
18
|
+
end
|
19
|
+
|
20
|
+
def document
|
21
|
+
@document ||= []
|
22
|
+
end
|
23
|
+
|
24
|
+
def erd(&block)
|
25
|
+
add(erd_header)
|
26
|
+
block.arity == 1 ? block[self] : instance_eval(&block)
|
27
|
+
add(erd_footer)
|
28
|
+
end
|
29
|
+
|
30
|
+
def erd_footer
|
31
|
+
"```"
|
32
|
+
end
|
33
|
+
|
34
|
+
def erd_header
|
35
|
+
[
|
36
|
+
"```mermaid",
|
37
|
+
"erDiagram",
|
38
|
+
" %% --------------------------------------------------------",
|
39
|
+
" %% Entity-Relationship Diagram",
|
40
|
+
" %% --------------------------------------------------------",
|
41
|
+
""
|
42
|
+
].join("\n")
|
43
|
+
end
|
44
|
+
|
45
|
+
def erd_relation(relation)
|
46
|
+
left_model_name = relation[:LeftModelName].tr(":", "-")
|
47
|
+
right_model_name = relation[:RightModelName].tr(":", "-")
|
48
|
+
comment = is_show_comment ? ": \"#{relation[:Comment]}\"" : ": \"\""
|
49
|
+
|
50
|
+
" #{left_model_name} #{relation[:LeftValue]}" \
|
51
|
+
"#{relation[:Line]}#{relation[:RightValue]} " \
|
52
|
+
"#{right_model_name} #{comment}"
|
53
|
+
end
|
54
|
+
|
55
|
+
def erd_table(table_name, model_name)
|
56
|
+
lines = [erd_table_header(table_name, model_name)]
|
57
|
+
lines << yield
|
58
|
+
lines << erd_table_footer
|
59
|
+
lines.join("\n")
|
60
|
+
end
|
61
|
+
|
62
|
+
def erd_table_column(column)
|
63
|
+
key = is_show_key ? column[:key] : ""
|
64
|
+
line = " #{column[:type]} #{column[:name]}"
|
65
|
+
line << " #{key}" unless key.empty?
|
66
|
+
line
|
67
|
+
end
|
68
|
+
|
69
|
+
def erd_table_header(table_name, model_name)
|
70
|
+
[
|
71
|
+
" %% table name: #{table_name}",
|
72
|
+
" #{model_name.tr(":", "-")}{"
|
73
|
+
].join("\n")
|
74
|
+
end
|
75
|
+
|
76
|
+
def erd_table_footer
|
77
|
+
[
|
78
|
+
" }",
|
79
|
+
""
|
80
|
+
].join("\n")
|
81
|
+
end
|
82
|
+
|
83
|
+
def header(text)
|
84
|
+
"# #{text}\n"
|
85
|
+
end
|
86
|
+
|
87
|
+
def generate(&block)
|
88
|
+
block.arity == 1 ? block[self] : instance_eval(&block)
|
89
|
+
document.join("\n")
|
90
|
+
end
|
91
|
+
|
92
|
+
def link(text, url)
|
93
|
+
"[#{text}](#{url})"
|
94
|
+
end
|
95
|
+
|
96
|
+
def list_item(text)
|
97
|
+
"- #{text}"
|
98
|
+
end
|
99
|
+
|
100
|
+
def subheader(text)
|
101
|
+
"## #{text}\n"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails-mermaid_erd"
|
4
|
+
|
5
|
+
module MermaidErdMarkdown
|
6
|
+
class SourceData
|
7
|
+
def data
|
8
|
+
@data ||= RailsMermaidErd::Builder.model_data
|
9
|
+
end
|
10
|
+
|
11
|
+
def split_output(depth = 1)
|
12
|
+
source_models = data[:Models]
|
13
|
+
source_relations = data[:Relations]
|
14
|
+
output = []
|
15
|
+
|
16
|
+
source_models.each do |model|
|
17
|
+
model_names = [model[:ModelName]]
|
18
|
+
search_models = model_names
|
19
|
+
relations = []
|
20
|
+
|
21
|
+
depth.times do
|
22
|
+
found_relations = []
|
23
|
+
next_search_models = []
|
24
|
+
search_models.each do |search_model|
|
25
|
+
found_relations += related_models(search_model, source_relations)
|
26
|
+
next_search_models += related_model_names(search_model, found_relations)
|
27
|
+
end
|
28
|
+
search_models = next_search_models
|
29
|
+
model_names += search_models
|
30
|
+
relations += found_relations
|
31
|
+
end
|
32
|
+
|
33
|
+
output << {
|
34
|
+
Models: models(model_names.uniq, source_models),
|
35
|
+
Relations: relations.uniq
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
output
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def models(model_names, source_models)
|
45
|
+
model_names.map do |model_name|
|
46
|
+
source_models.find { |m| m[:ModelName] == model_name }
|
47
|
+
end.compact
|
48
|
+
end
|
49
|
+
|
50
|
+
def related_model_names(model_name, relations)
|
51
|
+
relations.map do |r|
|
52
|
+
r[:LeftModelName] == model_name ? r[:RightModelName] : r[:LeftModelName]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def related_models(model_name, relations)
|
57
|
+
relations.select do |relation|
|
58
|
+
relation[:LeftModelName] == model_name ||
|
59
|
+
relation[:RightModelName] == model_name
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -1,109 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "rails-mermaid_erd_markdown/
|
4
|
-
require "rails-mermaid_erd"
|
5
|
-
require "digest/md5"
|
3
|
+
require_relative "rails-mermaid_erd_markdown/generator"
|
6
4
|
require "rake"
|
7
5
|
require "rake/dsl_definition"
|
8
|
-
require "pathname"
|
9
|
-
require "logger"
|
10
6
|
|
11
7
|
module MermaidErdMarkdown
|
12
8
|
extend Rake::DSL
|
13
9
|
|
14
10
|
class << self
|
15
|
-
attr_writer :logger
|
16
|
-
|
17
|
-
def logger
|
18
|
-
@logger ||= Logger.new($stdout).tap do |log|
|
19
|
-
log.progname = name
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def configuration
|
24
|
-
@configuration ||= MermaidErdMarkdown::Configuration.new
|
25
|
-
end
|
26
|
-
|
27
11
|
def perform
|
28
|
-
|
29
|
-
existing_erd_path = Pathname.new(configuration.output_path)
|
30
|
-
|
31
|
-
unless existing_erd_path.exist?
|
32
|
-
logger.info("ERD does not currently exist at result path. Creating...")
|
33
|
-
begin
|
34
|
-
create_erd_file(new_erd)
|
35
|
-
logger.info("ERD successfully created at #{configuration.output_path}")
|
36
|
-
rescue StandardError
|
37
|
-
logger.info("Could not create ERD. Output path is invalid.")
|
38
|
-
end
|
39
|
-
|
40
|
-
return
|
41
|
-
end
|
42
|
-
|
43
|
-
existing_erd = File.read(existing_erd_path)
|
44
|
-
update_erd_file(existing_erd, new_erd)
|
45
|
-
end
|
46
|
-
|
47
|
-
def update_erd_file(current_erd, new_erd)
|
48
|
-
# check if two diagrams are the same by comparing their MD5 hashes
|
49
|
-
if Digest::MD5.hexdigest(current_erd) == Digest::MD5.hexdigest(new_erd)
|
50
|
-
logger.info("ERD already exists and is up to date. Skipping...")
|
51
|
-
return
|
52
|
-
end
|
53
|
-
|
54
|
-
logger.info("ERD already exists but is out of date. Overwriting...")
|
55
|
-
File.write(configuration.output_path, new_erd)
|
56
|
-
logger.info("ERD successfully updated")
|
57
|
-
|
58
|
-
nil
|
59
|
-
end
|
60
|
-
|
61
|
-
def create_erd_file(erd)
|
62
|
-
File.write(configuration.output_path, erd)
|
63
|
-
|
64
|
-
nil
|
65
|
-
end
|
66
|
-
|
67
|
-
def generate_mermaid_erd
|
68
|
-
data = RailsMermaidErd::Builder.model_data
|
69
|
-
|
70
|
-
is_show_key = true
|
71
|
-
is_show_relation_comment = true
|
72
|
-
|
73
|
-
lines = ["```mermaid"]
|
74
|
-
lines << "erDiagram"
|
75
|
-
lines << " %% --------------------------------------------------------"
|
76
|
-
lines << " %% Entity-Relationship Diagram"
|
77
|
-
lines << " %% --------------------------------------------------------"
|
78
|
-
lines << ""
|
79
|
-
|
80
|
-
data[:Models].each do |model|
|
81
|
-
lines << " %% table name: #{model[:TableName]}"
|
82
|
-
lines << " #{model[:ModelName].tr(":", "-")}{"
|
83
|
-
|
84
|
-
model[:Columns].each do |column|
|
85
|
-
key = is_show_key ? column[:key] : ""
|
86
|
-
lines << " #{column[:type]} #{column[:name]} #{key} "
|
87
|
-
end
|
88
|
-
|
89
|
-
lines << " }"
|
90
|
-
lines << ""
|
91
|
-
end
|
92
|
-
|
93
|
-
data[:Relations].each do |relation|
|
94
|
-
left_model_name = relation[:LeftModelName].tr(":", "-")
|
95
|
-
right_model_name = relation[:RightModelName].tr(":", "-")
|
96
|
-
comment = is_show_relation_comment ? ": \"#{relation[:Comment]}\"" : ": \"\""
|
97
|
-
|
98
|
-
lines << " #{left_model_name} #{relation[:LeftValue]}#{relation[:Line]}#{relation[:RightValue]} #{right_model_name} #{comment}"
|
99
|
-
end
|
100
|
-
|
101
|
-
lines << "```"
|
102
|
-
lines.join("\n")
|
12
|
+
MermaidErdMarkdown::Generator.generate
|
103
13
|
end
|
104
14
|
end
|
105
15
|
|
106
|
-
desc "Generate/update mermaid ERD diagram for database Models."
|
16
|
+
desc "Generate/update mermaid ERD diagram(s) for database Models."
|
107
17
|
task generate_erd: :environment do
|
108
18
|
perform
|
109
19
|
end
|
@@ -8,7 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.authors = ["humzahkiani"]
|
9
9
|
spec.email = ["89326566+humzahkiani@users.noreply.github.com"]
|
10
10
|
|
11
|
-
spec.summary = "This is a rails gem that extends the rails-mermaid_erd gem to generate a mermaid ERD for Rails
|
11
|
+
spec.summary = "This is a rails gem that extends the rails-mermaid_erd gem to generate a mermaid ERD for Rails " \
|
12
|
+
"Models in markdown directly in source code."
|
12
13
|
spec.homepage = "https://github.com/humzahkiani/rails-mermaid_erd_markdown"
|
13
14
|
spec.license = "MIT"
|
14
15
|
spec.required_ruby_version = ">= 2.6.0"
|
@@ -16,7 +17,7 @@ Gem::Specification.new do |spec|
|
|
16
17
|
spec.metadata["homepage_uri"] = spec.homepage
|
17
18
|
spec.metadata["source_code_uri"] = "https://github.com/humzahkiani/rails-mermaid_erd_markdown"
|
18
19
|
spec.metadata["changelog_uri"] = "https://github.com/humzahkiani/rails-mermaid_erd_markdown/blob/main/CHANGELOG.md"
|
19
|
-
|
20
|
+
spec.metadata["github_repo"] = "ssh://github.com/humzahkiani/rails-mermaid_erd_markdown"
|
20
21
|
# Specify which files should be added to the gem when it is released.
|
21
22
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
22
23
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
@@ -26,10 +27,11 @@ Gem::Specification.new do |spec|
|
|
26
27
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
27
28
|
spec.require_paths = ["lib"]
|
28
29
|
|
29
|
-
#
|
30
|
+
# Runtime Dependencies
|
30
31
|
spec.add_dependency "rails", ">= 5.2"
|
31
32
|
spec.add_dependency "rails-mermaid_erd", "~> 0.4.2"
|
32
33
|
|
33
34
|
# For more information and examples about making a new gem, check out our
|
34
35
|
# guide at: https://bundler.io/guides/creating_gem.html
|
36
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
35
37
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
```mermaid
|
2
|
+
erDiagram
|
3
|
+
%% --------------------------------------------------------
|
4
|
+
%% Entity-Relationship Diagram
|
5
|
+
%% --------------------------------------------------------
|
6
|
+
|
7
|
+
%% table name: users
|
8
|
+
User{
|
9
|
+
integer id PK
|
10
|
+
string name
|
11
|
+
string email
|
12
|
+
datetime created_at
|
13
|
+
datetime updated_at
|
14
|
+
}
|
15
|
+
|
16
|
+
%% table name: profiles
|
17
|
+
Profile{
|
18
|
+
integer id PK
|
19
|
+
text bio
|
20
|
+
integer user_id FK
|
21
|
+
datetime created_at
|
22
|
+
datetime updated_at
|
23
|
+
}
|
24
|
+
|
25
|
+
%% table name: articles
|
26
|
+
Article{
|
27
|
+
integer id PK
|
28
|
+
string title
|
29
|
+
text content
|
30
|
+
integer user_id FK
|
31
|
+
datetime created_at
|
32
|
+
datetime updated_at
|
33
|
+
}
|
34
|
+
|
35
|
+
%% table name: comments
|
36
|
+
Comment{
|
37
|
+
integer id PK
|
38
|
+
string commenter
|
39
|
+
text body
|
40
|
+
integer article_id FK
|
41
|
+
datetime created_at
|
42
|
+
datetime updated_at
|
43
|
+
}
|
44
|
+
|
45
|
+
Article }o--|| User : "BT:user"
|
46
|
+
Profile }o--|| User : "BT:user"
|
47
|
+
Comment }o--|| Article : "BT:article"
|
48
|
+
```
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# Entity Relationship Diagrams
|
2
|
+
|
3
|
+
Each model has its own ERD diagram. The diagram shows the selected model, plus 1 associated model(s) deep. Click on the model name to view the diagram.
|
4
|
+
|
5
|
+
## Models
|
6
|
+
|
7
|
+
- [User](../User.md)
|
8
|
+
- [Profile](../Profile.md)
|
9
|
+
- [Article](../Article.md)
|
10
|
+
- [Comment](../Comment.md)
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# User Entity-Relationship Diagram
|
2
|
+
|
3
|
+
## Associated Models
|
4
|
+
|
5
|
+
- [Article](../app/models/ERD_Article.md)
|
6
|
+
- [Profile](../app/models/ERD_Profile.md)
|
7
|
+
|
8
|
+
## Entity-Relationship Diagram
|
9
|
+
|
10
|
+
```mermaid
|
11
|
+
erDiagram
|
12
|
+
%% --------------------------------------------------------
|
13
|
+
%% Entity-Relationship Diagram
|
14
|
+
%% --------------------------------------------------------
|
15
|
+
|
16
|
+
%% table name: users
|
17
|
+
User{
|
18
|
+
integer id PK
|
19
|
+
string name
|
20
|
+
string email
|
21
|
+
datetime created_at
|
22
|
+
datetime updated_at
|
23
|
+
}
|
24
|
+
|
25
|
+
%% table name: articles
|
26
|
+
Article{
|
27
|
+
integer id PK
|
28
|
+
string title
|
29
|
+
text content
|
30
|
+
integer user_id FK
|
31
|
+
datetime created_at
|
32
|
+
datetime updated_at
|
33
|
+
}
|
34
|
+
|
35
|
+
%% table name: profiles
|
36
|
+
Profile{
|
37
|
+
integer id PK
|
38
|
+
text bio
|
39
|
+
integer user_id FK
|
40
|
+
datetime created_at
|
41
|
+
datetime updated_at
|
42
|
+
}
|
43
|
+
|
44
|
+
Article }o--|| User : "BT:user"
|
45
|
+
Profile }o--|| User : "BT:user"
|
46
|
+
```
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module MockData
|
2
|
+
module Models
|
3
|
+
def user_model
|
4
|
+
{
|
5
|
+
TableName: "users", ModelName: "User", IsModelExist: true,
|
6
|
+
Columns: [
|
7
|
+
{ name: "id", type: :integer, key: "PK", comment: nil },
|
8
|
+
{ name: "name", type: :string, key: "", comment: nil },
|
9
|
+
{ name: "email", type: :string, key: "", comment: nil },
|
10
|
+
{ name: "created_at", type: :datetime, key: "", comment: nil },
|
11
|
+
{ name: "updated_at", type: :datetime, key: "", comment: nil }
|
12
|
+
]
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
def profile_model
|
17
|
+
{
|
18
|
+
TableName: "profiles", ModelName: "Profile", IsModelExist: true,
|
19
|
+
Columns: [
|
20
|
+
{ name: "id", type: :integer, key: "PK", comment: nil },
|
21
|
+
{ name: "bio", type: :text, key: "", comment: nil },
|
22
|
+
{ name: "user_id", type: :integer, key: "FK", comment: nil },
|
23
|
+
{ name: "created_at", type: :datetime, key: "", comment: nil },
|
24
|
+
{ name: "updated_at", type: :datetime, key: "", comment: nil }
|
25
|
+
]
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def article_model
|
30
|
+
{
|
31
|
+
TableName: "articles", ModelName: "Article", IsModelExist: true,
|
32
|
+
Columns: [
|
33
|
+
{ name: "id", type: :integer, key: "PK", comment: nil },
|
34
|
+
{ name: "title", type: :string, key: "", comment: nil },
|
35
|
+
{ name: "content", type: :text, key: "", comment: nil },
|
36
|
+
{ name: "user_id", type: :integer, key: "FK", comment: nil },
|
37
|
+
{ name: "created_at", type: :datetime, key: "", comment: nil },
|
38
|
+
{ name: "updated_at", type: :datetime, key: "", comment: nil }
|
39
|
+
]
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def comment_model
|
44
|
+
{
|
45
|
+
TableName: "comments", ModelName: "Comment", IsModelExist: true,
|
46
|
+
Columns: [
|
47
|
+
{ name: "id", type: :integer, key: "PK", comment: nil },
|
48
|
+
{ name: "commenter", type: :string, key: "", comment: nil },
|
49
|
+
{ name: "body", type: :text, key: "", comment: nil },
|
50
|
+
{ name: "article_id", type: :integer, key: "FK", comment: nil },
|
51
|
+
{ name: "created_at", type: :datetime, key: "", comment: nil },
|
52
|
+
{ name: "updated_at", type: :datetime, key: "", comment: nil }
|
53
|
+
]
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
def article_relation
|
58
|
+
{
|
59
|
+
LeftModelName: "Article",
|
60
|
+
LeftValue: "}o",
|
61
|
+
Line: "--",
|
62
|
+
RightModelName: "User",
|
63
|
+
RightValue: "||",
|
64
|
+
Comment: "BT:user"
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
def profile_relation
|
69
|
+
{
|
70
|
+
LeftModelName: "Profile",
|
71
|
+
LeftValue: "}o",
|
72
|
+
Line: "--",
|
73
|
+
RightModelName: "User",
|
74
|
+
RightValue: "||",
|
75
|
+
Comment: "BT:user"
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
def comment_relation
|
80
|
+
{
|
81
|
+
LeftModelName: "Comment",
|
82
|
+
LeftValue: "}o",
|
83
|
+
Line: "--",
|
84
|
+
RightModelName: "Article",
|
85
|
+
RightValue: "||",
|
86
|
+
Comment: "BT:article"
|
87
|
+
}
|
88
|
+
end
|
89
|
+
|
90
|
+
def stubbed_model_data
|
91
|
+
{
|
92
|
+
Models: [
|
93
|
+
user_model,
|
94
|
+
profile_model,
|
95
|
+
article_model,
|
96
|
+
comment_model
|
97
|
+
], Relations: [
|
98
|
+
article_relation,
|
99
|
+
profile_relation,
|
100
|
+
comment_relation
|
101
|
+
]
|
102
|
+
}
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|