rails-mermaid_erd 0.3.0 → 0.4.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
  SHA256:
3
- metadata.gz: 1a0b049ccbaa1ec74fd4f0bc0c55e9b1ca066ac4f9e7b624591e1626edbbcb47
4
- data.tar.gz: 0c2a7bf4cb12c29f7623e2ceaef53de385f9a2dd9f6d3596786849623e9979c6
3
+ metadata.gz: 8e4055c271a20a0d95b98c24eea1149feb9ff6ab9333a0fd57e4483264b61ac8
4
+ data.tar.gz: 8575c2a15370b7d9467dc32bbcf237cf26a0593748e6c0303b56e17c8960a99a
5
5
  SHA512:
6
- metadata.gz: 7894f5a5b2717404fb8593295138466678158de760e4704235dbd64ba968dfb180334df4610f615edf670df564d7aca1bfa869a6ba5f54e033883dba80add955
7
- data.tar.gz: 44011954159232651066fb8a12b58ea27877055a12a7c677641dd37981bfb98ecf3d3caed1c0797ee0fb38f3d61bc8e9050585782d31203d262c5dede90fee46
6
+ metadata.gz: fbeee181795d8ea1a191f39b7bb015dbfc9e8db791d9c55af8d2d752e6cd577a41e3ebb189a4fa865868e8ccc97f8c1548e76c6a21b11f2125126d881717ac14
7
+ data.tar.gz: 9e0d419707357cb622495a78424b4704a8188cacbb92927f5dd19d7a35b53a634d2948cca6bb079927eaeea6caef20ada027f389dd7a0fa0417ae499fab43e9f
@@ -0,0 +1,163 @@
1
+ require "yaml"
2
+
3
+ class RailsMermaidErd::Builder
4
+ class << self
5
+ def model_data
6
+ result = {
7
+ Models: [],
8
+ Relations: []
9
+ }
10
+
11
+ ::Rails.application.eager_load!
12
+ ::ActiveRecord::Base.descendants.sort_by(&:name).each do |defined_model|
13
+ next unless defined_model.table_exists?
14
+ next if defined_model.name.include?("HABTM_")
15
+ next if defined_model.table_name.blank?
16
+
17
+ model = {
18
+ TableName: defined_model.table_name,
19
+ ModelName: defined_model.name,
20
+ IsModelExist: true,
21
+ Columns: []
22
+ }
23
+
24
+ foreign_keys = ::ActiveRecord::Schema.foreign_keys(defined_model.table_name).map { |k| k.options[:column] }
25
+ primary_key = defined_model.primary_key
26
+ defined_model.columns.each do |column|
27
+ key = ""
28
+ if column.name == primary_key
29
+ key = "PK"
30
+ elsif foreign_keys.include?(column.name)
31
+ key = "FK"
32
+ end
33
+ model[:Columns] << {
34
+ name: column.name,
35
+ type: column.type,
36
+ key: key,
37
+ comment: column.comment
38
+ }
39
+ end
40
+
41
+ result[:Models] << model
42
+
43
+ defined_model.reflect_on_all_associations(:has_many).each do |reflection|
44
+ reflection_model_name = get_reflection_model_name(reflection)
45
+
46
+ reverse_relation = result[:Relations].find { |r|
47
+ if reflection.options[:through]
48
+ r[:RightModelName] == model[:ModelName] && r[:LeftModelName] == reflection_model_name && r[:Line] == ".."
49
+ else
50
+ r[:RightModelName] == model[:ModelName] && r[:LeftModelName] == reflection_model_name && r[:Line] == "--"
51
+ end
52
+ }
53
+ if reverse_relation
54
+ reverse_relation[:Comment] = if reflection.options[:through]
55
+ "#{reverse_relation[:Comment]}, HMT:#{reflection.name}"
56
+ else
57
+ "#{reverse_relation[:Comment]}, HM:#{reflection.name}"
58
+ end
59
+ else
60
+ result[:Relations] << {
61
+ LeftModelName: model[:ModelName],
62
+ LeftValue: reflection.options[:through] ? "}o" : "||",
63
+ Line: reflection.options[:through] ? ".." : "--",
64
+ RightModelName: reflection_model_name,
65
+ RightValue: "o{",
66
+ Comment: reflection.options[:through] ? "HMT:#{reflection.name}" : "HM:#{reflection.name}"
67
+ }
68
+ end
69
+ end
70
+
71
+ defined_model.reflect_on_all_associations(:has_and_belongs_to_many).each do |reflection|
72
+ reflection_model_name = get_reflection_model_name(reflection)
73
+
74
+ reverse_relation = result[:Relations].find { |r| r[:RightModelName] == model[:ModelName] && r[:LeftModelName] == reflection_model_name }
75
+ if reverse_relation
76
+ reverse_relation[:Comment] = "HABTM"
77
+ else
78
+ result[:Relations] << {
79
+ LeftModelName: model[:ModelName],
80
+ LeftValue: "}o",
81
+ Line: "..",
82
+ RightModelName: reflection_model_name,
83
+ RightValue: "o{",
84
+ Comment: "HABTM"
85
+ }
86
+ end
87
+ end
88
+
89
+ defined_model.reflect_on_all_associations(:belongs_to).each do |reflection|
90
+ reflection_model_name = get_reflection_model_name(reflection)
91
+
92
+ reverse_relation = result[:Relations].find { |r| r[:RightModelName] == model[:ModelName] && r[:LeftModelName] == reflection_model_name }
93
+ if reverse_relation
94
+ if (::Rails.application.config.active_record.belongs_to_required_by_default && reflection.options[:optional]) || (!::Rails.application.config.active_record.belongs_to_required_by_default && !reflection.options[:requried])
95
+ reverse_relation[:LeftValue] = "|o"
96
+ end
97
+ reverse_relation[:Comment] = "#{reverse_relation[:Comment]}, BT:#{reflection.name}"
98
+ else
99
+ right_value = if (::Rails.application.config.active_record.belongs_to_required_by_default && reflection.options[:optional]) || (!::Rails.application.config.active_record.belongs_to_required_by_default && !reflection.options[:requried])
100
+ "o|"
101
+ else
102
+ "||"
103
+ end
104
+ result[:Relations] << {
105
+ LeftModelName: model[:ModelName],
106
+ LeftValue: "}o",
107
+ Line: "--",
108
+ RightModelName: reflection_model_name,
109
+ RightValue: right_value,
110
+ Comment: "BT:#{reflection.name}"
111
+ }
112
+ end
113
+ end
114
+
115
+ defined_model.reflect_on_all_associations(:has_one).each do |reflection|
116
+ reflection_model_name = get_reflection_model_name(reflection)
117
+
118
+ reverse_relation = result[:Relations].find { |r|
119
+ if reflection.options[:through]
120
+ r[:RightModelName] == model[:ModelName] && r[:LeftModelName] == reflection_model_name && r[:Line] == ".."
121
+ else
122
+ r[:RightModelName] == model[:ModelName] && r[:LeftModelName] == reflection_model_name && r[:Line] == "--"
123
+ end
124
+ }
125
+ if reverse_relation
126
+ reverse_relation[:LeftValue] = "|o"
127
+ reverse_relation[:Comment] = if reflection.options[:through]
128
+ "#{reverse_relation[:Comment]}, HOT:#{reflection.name}"
129
+ else
130
+ "#{reverse_relation[:Comment]}, HO:#{reflection.name}"
131
+ end
132
+ else
133
+ result[:Relations] << {
134
+ LeftModelName: model[:ModelName],
135
+ LeftValue: reflection.options[:through] ? "}o" : "||",
136
+ Line: reflection.options[:through] ? ".." : "--",
137
+ RightModelName: reflection_model_name,
138
+ RightValue: "o|",
139
+ Comment: reflection.options[:through] ? "HOT:#{reflection.name}" : "HO:#{reflection.name}"
140
+ }
141
+ end
142
+ end
143
+ end
144
+
145
+ result
146
+ end
147
+
148
+ # Doc: https://guides.rubyonrails.org/association_basics.html
149
+ def get_reflection_model_name(reflection)
150
+ if reflection.options[:class_name]
151
+ reflection.options[:class_name].to_s.classify
152
+ elsif reflection.options[:through]
153
+ if reflection.options[:source]
154
+ reflection.options[:source].to_s.classify
155
+ else
156
+ reflection.class_name
157
+ end
158
+ else
159
+ reflection.class_name
160
+ end
161
+ end
162
+ end
163
+ end
@@ -1,21 +1,19 @@
1
1
  require "yaml"
2
2
 
3
- module RailsMermaidErd
4
- class Configuration
5
- attr_accessor :result_path
3
+ class RailsMermaidErd::Configuration
4
+ attr_accessor :result_path
6
5
 
7
- def initialize
8
- config = {
9
- result_path: "mermaid_erd/index.html"
10
- }
6
+ def initialize
7
+ config = {
8
+ result_path: "mermaid_erd/index.html"
9
+ }
11
10
 
12
- config_file = Rails.root.join("config/mermaid_erd.yml")
13
- if File.exist?(config_file)
14
- custom_config = YAML.load(config_file.read).symbolize_keys
15
- config = config.merge(custom_config)
16
- end
17
-
18
- @result_path = config[:result_path]
11
+ config_file = Rails.root.join("config/mermaid_erd.yml")
12
+ if File.exist?(config_file)
13
+ custom_config = YAML.load(config_file.read).symbolize_keys
14
+ config = config.merge(custom_config)
19
15
  end
16
+
17
+ @result_path = config[:result_path]
20
18
  end
21
19
  end
@@ -1,3 +1,3 @@
1
1
  module RailsMermaidErd
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -4,6 +4,7 @@ require "rake"
4
4
  require "rake/dsl_definition"
5
5
  require_relative "rails-mermaid_erd/version"
6
6
  require_relative "rails-mermaid_erd/configuration"
7
+ require_relative "rails-mermaid_erd/builder"
7
8
 
8
9
  module RailsMermaidErd
9
10
  extend Rake::DSL
@@ -16,206 +17,7 @@ module RailsMermaidErd
16
17
 
17
18
  desc "Generate Mermaid ERD."
18
19
  task mermaid_erd: :environment do
19
- result = {
20
- Models: [],
21
- Relations: []
22
- }
23
-
24
- ::Rails.application.eager_load!
25
- ::ActiveRecord::Base.descendants.each do |defined_model|
26
- next unless defined_model.table_exists?
27
-
28
- next if defined_model.name.include?("HABTM_")
29
-
30
- model = {
31
- TableName: defined_model.table_name,
32
- ModelName: defined_model.name,
33
- IsModelExist: true,
34
- Columns: []
35
- }
36
-
37
- next if defined_model.table_name.blank?
38
-
39
- foreign_keys = ::ActiveRecord::Schema.foreign_keys(defined_model.table_name).map { |k| k.options[:column] }
40
- primary_key = defined_model.primary_key
41
-
42
- defined_model.columns.each do |column|
43
- key = ""
44
- if column.name == primary_key
45
- key = "PK"
46
- elsif foreign_keys.include?(column.name)
47
- key = "FK"
48
- end
49
- model[:Columns] << {
50
- name: column.name,
51
- type: column.type,
52
- key: key,
53
- comment: column.comment
54
- }
55
- end
56
-
57
- result[:Models] << model
58
-
59
- next unless model[:IsModelExist]
60
-
61
- defined_model.reflect_on_all_associations(:has_many).each do |h|
62
- if h.options[:through]
63
- next
64
- end
65
- if h.options[:class_name]
66
- reverse_relation = result[:Relations].find { |r| r[:RightModelName] == model[:ModelName] && r[:LeftModelName] == h.options[:class_name] }
67
- if reverse_relation
68
- reverse_relation[:Comment] = if reverse_relation[:Comment] == ""
69
- "has_many #{h.name}"
70
- else
71
- "#{reverse_relation[:Comment]} : has_many #{h.name}"
72
- end
73
- else
74
- result[:Relations] << {
75
- LeftModelName: model[:ModelName],
76
- LeftValue: "||",
77
- RightModelName: h.name.to_s.classify,
78
- RightValue: "o{",
79
- Comment: "has_many #{h.name}"
80
- }
81
- end
82
- else
83
- reverse_relation = result[:Relations].find { |r| r[:RightModelName] == model[:ModelName] && r[:LeftModelName] == h.name.to_s.classify }
84
- if reverse_relation
85
- else
86
- result[:Relations] << {
87
- LeftModelName: model[:ModelName],
88
- LeftValue: "||",
89
- RightModelName: h.name.to_s.classify,
90
- RightValue: "o{",
91
- Comment: ""
92
- }
93
- end
94
- end
95
- end
96
-
97
- defined_model.reflect_on_all_associations(:has_and_belongs_to_many).each do |h|
98
- reverse_relation = if h.options[:class_name]
99
- result[:Relations].find { |r| r[:RightModelName] == model[:ModelName] && r[:LeftModelName] == h.options[:class_name] }
100
- else
101
- result[:Relations].find { |r| r[:RightModelName] == model[:ModelName] && r[:LeftModelName] == h.name.to_s.classify }
102
- end
103
- if reverse_relation
104
- reverse_relation[:Comment] = "HABTM"
105
- else
106
- result[:Relations] << {
107
- LeftModelName: model[:ModelName],
108
- LeftValue: "}o",
109
- RightModelName: h.name.to_s.classify,
110
- RightValue: "o{",
111
- Comment: "HABTM"
112
- }
113
- end
114
- end
115
-
116
- defined_model.reflect_on_all_associations(:belongs_to).each do |h|
117
- if h.options[:class_name]
118
- reverse_relation = result[:Relations].find { |r| r[:RightModelName] == model[:ModelName] && r[:LeftModelName] == h.options[:class_name] }
119
-
120
- if reverse_relation
121
- if (::Rails.application.config.active_record.belongs_to_required_by_default && h.options[:optional]) || (!::Rails.application.config.active_record.belongs_to_required_by_default && !h.options[:requried])
122
- reverse_relation[:LeftValue] = "|o"
123
- end
124
- reverse_relation[:Comment] = if reverse_relation[:Comment] == ""
125
- "belongs_to #{h.name}"
126
- else
127
- "#{reverse_relation[:Comment]} : belongs_to #{h.name}"
128
- end
129
- else
130
- result[:Relations] << if (::Rails.application.config.active_record.belongs_to_required_by_default && h.options[:optional]) || (!::Rails.application.config.active_record.belongs_to_required_by_default && !h.options[:requried])
131
- {
132
- LeftModelName: model[:ModelName],
133
- LeftValue: "}o",
134
- RightModelName: h.options[:class_name],
135
- RightValue: "o|",
136
- Comment: "belongs_to #{h.name}"
137
- }
138
- else
139
- {
140
- LeftModelName: model[:ModelName],
141
- LeftValue: "}o",
142
- RightModelName: h.options[:class_name],
143
- RightValue: "||",
144
- Comment: "belongs_to #{h.name}"
145
- }
146
- end
147
- end
148
- else
149
- reverse_relation = result[:Relations].find { |r| r[:RightModelName] == model[:ModelName] && r[:LeftModelName] == h.name.to_s.classify }
150
-
151
- if reverse_relation
152
- if (::Rails.application.config.active_record.belongs_to_required_by_default && h.options[:optional]) || (!::Rails.application.config.active_record.belongs_to_required_by_default && !h.options[:requried])
153
- reverse_relation[:LeftValue] = "|o"
154
- end
155
- else
156
- result[:Relations] << if (::Rails.application.config.active_record.belongs_to_required_by_default && h.options[:optional]) || (!::Rails.application.config.active_record.belongs_to_required_by_default && !h.options[:requried])
157
- {
158
- LeftModelName: model[:ModelName],
159
- LeftValue: "}o",
160
- RightModelName: h.name.to_s.classify,
161
- RightValue: "o|",
162
- Comment: ""
163
- }
164
- else
165
- {
166
- LeftModelName: model[:ModelName],
167
- LeftValue: "}o",
168
- RightModelName: h.name.to_s.classify,
169
- RightValue: "||",
170
- Comment: ""
171
- }
172
- end
173
- end
174
- end
175
- end
176
-
177
- defined_model.reflect_on_all_associations(:has_one).each do |h|
178
- if h.options[:class_name]
179
- reverse_relation = result[:Relations].find { |r| r[:RightModelName] == model[:ModelName] && r[:LeftModelName] == h.options[:class_name] }
180
- if reverse_relation
181
- reverse_relation[:LeftValue] = "|o"
182
- reverse_relation[:Comment] = if reverse_relation[:Comment] == ""
183
- "has_one #{h.name}"
184
- else
185
- "#{reverse_relation[:Comment]} : has_one #{h.name}"
186
- end
187
-
188
- if h.options[:through]
189
- next
190
- end
191
- else
192
- result[:Relations] << {
193
- LeftModelName: model[:ModelName],
194
- LeftValue: "||",
195
- RightModelName: h.options[:class_name],
196
- RightValue: "o|",
197
- Comment: "has_one #{h.name}"
198
- }
199
- end
200
- else
201
- reverse_relation = result[:Relations].find { |r| r[:RightModelName] == model[:ModelName] && r[:LeftModelName] == h.name.to_s.classify }
202
- if reverse_relation
203
- reverse_relation[:LeftValue] = "|o"
204
- if h.options[:through]
205
- next
206
- end
207
- else
208
- result[:Relations] << {
209
- LeftModelName: model[:ModelName],
210
- LeftValue: "||",
211
- RightModelName: h.name.to_s.classify,
212
- RightValue: "o|",
213
- Comment: "has_one #{h.name}"
214
- }
215
- end
216
- end
217
- end
218
- end
20
+ result = RailsMermaidErd::Builder.model_data
219
21
 
220
22
  version = VERSION
221
23
  app_name = ::Rails.application.class.try(:parent_name) || ::Rails.application.class.try(:module_parent_name)
@@ -422,7 +422,7 @@
422
422
  });
423
423
 
424
424
  filteredData.value.Relations.forEach(relation => {
425
- lines.push(` ${relation.LeftModelName.replace(/:/g, '-')} ${relation.LeftValue}--${relation.RightValue} ${relation.RightModelName.replace(/:/g, '-')} : "${relation.Comment}"`)
425
+ lines.push(` ${relation.LeftModelName.replace(/:/g, '-')} ${relation.LeftValue}${relation.Line}${relation.RightValue} ${relation.RightModelName.replace(/:/g, '-')} : "${relation.Comment}"`)
426
426
  });
427
427
 
428
428
  return lines.join("\n")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-mermaid_erd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - 肥溜め
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-10-12 00:00:00.000000000 Z
12
+ date: 2022-10-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -53,6 +53,20 @@ dependencies:
53
53
  - - ">="
54
54
  - !ruby/object:Gem::Version
55
55
  version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: simplecov
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
56
70
  - !ruby/object:Gem::Dependency
57
71
  name: standard
58
72
  requirement: !ruby/object:Gem::Requirement
@@ -92,6 +106,7 @@ files:
92
106
  - Rakefile
93
107
  - lib/assets/logo.svg
94
108
  - lib/rails-mermaid_erd.rb
109
+ - lib/rails-mermaid_erd/builder.rb
95
110
  - lib/rails-mermaid_erd/configuration.rb
96
111
  - lib/rails-mermaid_erd/version.rb
97
112
  - lib/templates/index.html.erb