Skip to content

Commit

Permalink
Merge pull request #405 from ahmedash95/support-mermaid
Browse files Browse the repository at this point in the history
Add optional Mermaid support
  • Loading branch information
kerrizor committed May 17, 2023
2 parents 52cb2ce + 2f3950b commit 7c66258
Show file tree
Hide file tree
Showing 8 changed files with 429 additions and 13 deletions.
11 changes: 10 additions & 1 deletion examples/generate.rb
Expand Up @@ -3,6 +3,7 @@

require "active_record"
require "rails_erd/diagram/graphviz"
require "rails_erd/diagram/mermaid"
require "active_support/dependencies"

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

puts " - #{notation} notation saved to #{outfile}"
puts " - Graphviz #{notation} notation saved to #{outfile}"
end
end

filename = File.expand_path("#{output_dir}/#{name}", File.dirname(__FILE__))
default_options = { :filetype => "txt", :filename => filename }
specific_options = eval((File.read("#{path}/options.rb") rescue "")) || {}

outfile = RailsERD::Diagram::Mermaid.new(domain, default_options.merge(specific_options)).create
puts " - Mermaid saved to #{outfile}"

puts
ensure
# Completely remove all loaded Active Record models.
Expand Down
1 change: 1 addition & 0 deletions lib/rails_erd.rb
Expand Up @@ -36,6 +36,7 @@ class << self

def default_options
ActiveSupport::OrderedOptions[
:generator, :graphviz,
:attributes, :content,
:disconnected, true,
:filename, "erd",
Expand Down
19 changes: 16 additions & 3 deletions lib/rails_erd/cli.rb
Expand Up @@ -5,14 +5,19 @@
separator ""
separator "Diagram options:"

option :generator do
long "--generator=Generator"
desc "Generator to use (graphviz or mermaid). Defaults to graphviz."
end

option :title do
long "--title=TITLE"
desc "Replace default diagram title with a custom one."
end

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

option :attributes do
Expand Down Expand Up @@ -159,7 +164,7 @@ def start

def initialize(path, options)
@path, @options = path, options
require "rails_erd/diagram/graphviz"
require "rails_erd/diagram/graphviz" if options.generator == :graphviz
end

def start
Expand Down Expand Up @@ -196,9 +201,17 @@ def load_application
rescue TypeError
end

def generator
if options.generator == :mermaid
RailsERD::Diagram::Mermaid
else
RailsERD::Diagram::Graphviz
end
end

def create_diagram
$stderr.puts "Generating entity-relationship diagram for #{ActiveRecord::Base.descendants.length} models..."
file = RailsERD::Diagram::Graphviz.create(options)
file = generator.create(options)
$stderr.puts "Diagram saved to '#{file}'."
`open #{file}` if options[:open]
end
Expand Down
2 changes: 1 addition & 1 deletion lib/rails_erd/config.rb
Expand Up @@ -61,7 +61,7 @@ def normalize_value(key, value)
end

# <symbol>
when :filetype, :notation
when :filetype, :notation, :generator
value.to_sym

# [<string>]
Expand Down
78 changes: 78 additions & 0 deletions lib/rails_erd/diagram/mermaid.rb
@@ -0,0 +1,78 @@
# encoding: utf-8
require "rails_erd/diagram"
require "erb"

module RailsERD
class Diagram
class Mermaid < Diagram

attr_accessor :graph

setup do
self.graph = ["classDiagram"]

# hard code to RL to make it easier to view diagrams from GitHub
self.graph << "\tdirection RL"
end

each_entity do |entity, attributes|
graph << "\tclass `#{entity}`"

attributes.each do | attr|
graph << "\t`#{entity}` : +#{attr.type} #{attr.name}"
end
end

each_specialization do |specialization|
from, to = specialization.generalized, specialization.specialized
graph << "\t<<polymorphic>> `#{specialization.generalized}`"
graph << "\t #{from.name} <|-- #{to.name}"
end

each_relationship do |relationship|
from, to = relationship.source, relationship.destination
graph << "\t`#{from.name}` #{relation_arrow(relationship)} `#{to.name}`"

from.children.each do |child|
graph << "\t`#{child.name}` #{relation_arrow(relationship)} `#{to.name}`"
end

to.children.each do |child|
graph << "\t`#{from.name}` #{relation_arrow(relationship)} `#{child.name}`"
end
end

save do
raise "Saving diagram failed!\nOutput directory '#{File.dirname(filename)}' does not exist." unless File.directory?(File.dirname(filename))

File.write(filename.gsub(/\s/,"_"), graph.uniq.join("\n"))
filename
end

def filename
"#{options.filename}.mmd"
end

def relation_arrow(relationship)
arrow_body = arrow_body relationship
arrow_head = arrow_head relationship
arrow_tail = arrow_tail relationship

"#{arrow_tail}#{arrow_body}#{arrow_head}"
end

def arrow_body(relationship)
relationship.indirect? ? ".." : "--"
end

def arrow_head(relationship)
relationship.to_many? ? ">" : ""
end

def arrow_tail(relationship)
relationship.many_to? ? "<" : ""
end

end
end
end
25 changes: 18 additions & 7 deletions lib/rails_erd/tasks.rake
Expand Up @@ -8,10 +8,12 @@ end

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

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

task :generate => [:check_dependencies, :options, :load_models] do
task :generate => [:options, :check_dependencies, :load_models] do
include ErdRakeHelper

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

require "rails_erd/diagram/graphviz"
file = RailsERD::Diagram::Graphviz.create
file = case RailsERD.options.generator
when :mermaid
require "rails_erd/diagram/mermaid"
RailsERD::Diagram::Mermaid.create
when :graphviz
require "rails_erd/diagram/graphviz"
RailsERD::Diagram::Graphviz.create
else
raise "Unknown generator: #{RailsERD.options.generator}"
end


say "Done! Saved diagram to ./#{file}"
end
Expand Down

0 comments on commit 7c66258

Please sign in to comment.