Skip to content

Commit 7c66258

Browse files
authored
Merge pull request voormedia#405 from ahmedash95/support-mermaid
Add optional Mermaid support
2 parents 52cb2ce + 2f3950b commit 7c66258

File tree

8 files changed

+429
-13
lines changed

8 files changed

+429
-13
lines changed

examples/generate.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
require "active_record"
55
require "rails_erd/diagram/graphviz"
6+
require "rails_erd/diagram/mermaid"
67
require "active_support/dependencies"
78

89
output_dir = File.expand_path("output", ".")
@@ -44,9 +45,17 @@
4445
# Generate ERD.
4546
outfile = RailsERD::Diagram::Graphviz.new(domain, default_options.merge(specific_options)).create
4647

47-
puts " - #{notation} notation saved to #{outfile}"
48+
puts " - Graphviz #{notation} notation saved to #{outfile}"
4849
end
4950
end
51+
52+
filename = File.expand_path("#{output_dir}/#{name}", File.dirname(__FILE__))
53+
default_options = { :filetype => "txt", :filename => filename }
54+
specific_options = eval((File.read("#{path}/options.rb") rescue "")) || {}
55+
56+
outfile = RailsERD::Diagram::Mermaid.new(domain, default_options.merge(specific_options)).create
57+
puts " - Mermaid saved to #{outfile}"
58+
5059
puts
5160
ensure
5261
# Completely remove all loaded Active Record models.

lib/rails_erd.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class << self
3636

3737
def default_options
3838
ActiveSupport::OrderedOptions[
39+
:generator, :graphviz,
3940
:attributes, :content,
4041
:disconnected, true,
4142
:filename, "erd",

lib/rails_erd/cli.rb

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,19 @@
55
separator ""
66
separator "Diagram options:"
77

8+
option :generator do
9+
long "--generator=Generator"
10+
desc "Generator to use (graphviz or mermaid). Defaults to graphviz."
11+
end
12+
813
option :title do
914
long "--title=TITLE"
1015
desc "Replace default diagram title with a custom one."
1116
end
1217

1318
option :notation do
1419
long "--notation=STYLE"
15-
desc "Diagram notation style, one of simple, bachman, uml or crowsfoot."
20+
desc "Diagram notation style, one of simple, bachman, uml or crowsfoot (avaiable only with Graphviz engine)."
1621
end
1722

1823
option :attributes do
@@ -159,7 +164,7 @@ def start
159164

160165
def initialize(path, options)
161166
@path, @options = path, options
162-
require "rails_erd/diagram/graphviz"
167+
require "rails_erd/diagram/graphviz" if options.generator == :graphviz
163168
end
164169

165170
def start
@@ -196,9 +201,17 @@ def load_application
196201
rescue TypeError
197202
end
198203

204+
def generator
205+
if options.generator == :mermaid
206+
RailsERD::Diagram::Mermaid
207+
else
208+
RailsERD::Diagram::Graphviz
209+
end
210+
end
211+
199212
def create_diagram
200213
$stderr.puts "Generating entity-relationship diagram for #{ActiveRecord::Base.descendants.length} models..."
201-
file = RailsERD::Diagram::Graphviz.create(options)
214+
file = generator.create(options)
202215
$stderr.puts "Diagram saved to '#{file}'."
203216
`open #{file}` if options[:open]
204217
end

lib/rails_erd/config.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def normalize_value(key, value)
6161
end
6262

6363
# <symbol>
64-
when :filetype, :notation
64+
when :filetype, :notation, :generator
6565
value.to_sym
6666

6767
# [<string>]

lib/rails_erd/diagram/mermaid.rb

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# encoding: utf-8
2+
require "rails_erd/diagram"
3+
require "erb"
4+
5+
module RailsERD
6+
class Diagram
7+
class Mermaid < Diagram
8+
9+
attr_accessor :graph
10+
11+
setup do
12+
self.graph = ["classDiagram"]
13+
14+
# hard code to RL to make it easier to view diagrams from GitHub
15+
self.graph << "\tdirection RL"
16+
end
17+
18+
each_entity do |entity, attributes|
19+
graph << "\tclass `#{entity}`"
20+
21+
attributes.each do | attr|
22+
graph << "\t`#{entity}` : +#{attr.type} #{attr.name}"
23+
end
24+
end
25+
26+
each_specialization do |specialization|
27+
from, to = specialization.generalized, specialization.specialized
28+
graph << "\t<<polymorphic>> `#{specialization.generalized}`"
29+
graph << "\t #{from.name} <|-- #{to.name}"
30+
end
31+
32+
each_relationship do |relationship|
33+
from, to = relationship.source, relationship.destination
34+
graph << "\t`#{from.name}` #{relation_arrow(relationship)} `#{to.name}`"
35+
36+
from.children.each do |child|
37+
graph << "\t`#{child.name}` #{relation_arrow(relationship)} `#{to.name}`"
38+
end
39+
40+
to.children.each do |child|
41+
graph << "\t`#{from.name}` #{relation_arrow(relationship)} `#{child.name}`"
42+
end
43+
end
44+
45+
save do
46+
raise "Saving diagram failed!\nOutput directory '#{File.dirname(filename)}' does not exist." unless File.directory?(File.dirname(filename))
47+
48+
File.write(filename.gsub(/\s/,"_"), graph.uniq.join("\n"))
49+
filename
50+
end
51+
52+
def filename
53+
"#{options.filename}.mmd"
54+
end
55+
56+
def relation_arrow(relationship)
57+
arrow_body = arrow_body relationship
58+
arrow_head = arrow_head relationship
59+
arrow_tail = arrow_tail relationship
60+
61+
"#{arrow_tail}#{arrow_body}#{arrow_head}"
62+
end
63+
64+
def arrow_body(relationship)
65+
relationship.indirect? ? ".." : "--"
66+
end
67+
68+
def arrow_head(relationship)
69+
relationship.to_many? ? ">" : ""
70+
end
71+
72+
def arrow_tail(relationship)
73+
relationship.many_to? ? "<" : ""
74+
end
75+
76+
end
77+
end
78+
end

lib/rails_erd/tasks.rake

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ end
88

99
namespace :erd do
1010
task :check_dependencies do
11-
include GraphViz::Utils
12-
unless find_executable("dot", nil)
13-
raise "Unable to find GraphViz's \"dot\" executable. Please " \
14-
"visit https://voormedia.github.io/rails-erd/install.html for installation instructions."
11+
if RailsERD.options.generator == :graphviz
12+
include GraphViz::Utils
13+
unless find_executable("dot", nil)
14+
raise "#{RailsERD.options.generator} Unable to find GraphViz's \"dot\" executable. Please " \
15+
"visit https://voormedia.github.io/rails-erd/install.html for installation instructions."
16+
end
1517
end
1618
end
1719

@@ -58,13 +60,22 @@ namespace :erd do
5860
raise "Active Record was not loaded." unless defined? ActiveRecord
5961
end
6062

61-
task :generate => [:check_dependencies, :options, :load_models] do
63+
task :generate => [:options, :check_dependencies, :load_models] do
6264
include ErdRakeHelper
6365

6466
say "Generating Entity-Relationship Diagram for #{ActiveRecord::Base.descendants.length} models..."
6567

66-
require "rails_erd/diagram/graphviz"
67-
file = RailsERD::Diagram::Graphviz.create
68+
file = case RailsERD.options.generator
69+
when :mermaid
70+
require "rails_erd/diagram/mermaid"
71+
RailsERD::Diagram::Mermaid.create
72+
when :graphviz
73+
require "rails_erd/diagram/graphviz"
74+
RailsERD::Diagram::Graphviz.create
75+
else
76+
raise "Unknown generator: #{RailsERD.options.generator}"
77+
end
78+
6879

6980
say "Done! Saved diagram to ./#{file}"
7081
end

0 commit comments

Comments
 (0)