Class: RailsERD::Diagram::Mermaid

Inherits:
Diagram
  • Object
show all
Defined in:
lib/rails_erd/diagram/mermaid.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#graphObject

Returns the value of attribute graph.



11
12
13
# File 'lib/rails_erd/diagram/mermaid.rb', line 11

def graph
  @graph
end

Instance Method Details

#arrow_body(relationship) ⇒ Object



185
186
187
# File 'lib/rails_erd/diagram/mermaid.rb', line 185

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

#arrow_head(relationship) ⇒ Object



189
190
191
# File 'lib/rails_erd/diagram/mermaid.rb', line 189

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

#arrow_tail(relationship) ⇒ Object



193
194
195
# File 'lib/rails_erd/diagram/mermaid.rb', line 193

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

#attribute_key_marker(attr) ⇒ Object



169
170
171
172
173
174
# File 'lib/rails_erd/diagram/mermaid.rb', line 169

def attribute_key_marker(attr)
  markers = []
  markers << "PK" if attr.primary_key?
  markers << "FK" if attr.foreign_key?
  markers.empty? ? "" : " #{markers.join(',')}"
end

#build_class_diagram_entity(short_name, full_name, attributes) ⇒ Object

Build entity lines for classDiagram mode (used in clustering)



198
199
200
201
202
203
204
# File 'lib/rails_erd/diagram/mermaid.rb', line 198

def build_class_diagram_entity(short_name, full_name, attributes)
  lines = ["\t\tclass `#{short_name}`"]
  attributes.each do |attr|
    lines << "\t\t`#{short_name}` : +#{attr.type} #{attr.name}"
  end
  lines
end

#diagram_typeObject



107
108
109
# File 'lib/rails_erd/diagram/mermaid.rb', line 107

def diagram_type
  er_diagram? ? "erDiagram" : "classDiagram"
end

#draw_relation(from, to, relationship) ⇒ Object

Mermaid renders any entity a relationship names, so an edge to an entity that was filtered out would draw it back into the diagram. Skip those, as Graphviz already does.



117
118
119
120
121
122
123
124
125
# File 'lib/rails_erd/diagram/mermaid.rb', line 117

def draw_relation(from, to, relationship)
  return unless entity_drawn?(from.name) && entity_drawn?(to.name)

  graph << if er_diagram?
             "\t#{quote_entity_name(from.name)} #{er_relation_notation(relationship)} #{quote_entity_name(to.name)} : \"\""
           else
             "\t`#{from.name}` #{relation_arrow(relationship)} `#{to.name}`"
           end
end

#emit_clustered_entitiesObject

Emit entities grouped by namespace for clustering



207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/rails_erd/diagram/mermaid.rb', line 207

def emit_clustered_entities
  # Entities without namespace go first (outside any namespace block)
  @entities_by_namespace[""].each do |entity_lines|
    entity_lines.each { |line| graph << line.sub(/^\t\t/, "\t") }
  end

  # Then emit each namespace block
  @entities_by_namespace.each do |ns, entity_blocks|
    next if ns == ""

    # Convert Ruby namespace (Admin::Users) to Mermaid format (Admin.Users)
    mermaid_ns = ns.gsub("::", ".")
    graph << "\tnamespace #{mermaid_ns} {"
    entity_blocks.each do |entity_lines|
      entity_lines.each { |line| graph << line }
    end
    graph << "\t}"
  end
end

#entity_drawn?(name) ⇒ Boolean

Returns:

  • (Boolean)


127
128
129
# File 'lib/rails_erd/diagram/mermaid.rb', line 127

def entity_drawn?(name)
  @drawn_entity_names.include?(name.to_s)
end

#er_diagram?Boolean

Returns:

  • (Boolean)


111
112
113
# File 'lib/rails_erd/diagram/mermaid.rb', line 111

def er_diagram?
  options[:mermaid_style] == :erdiagram || options[:mermaid_style] == :er
end

#er_relation_notation(relationship) ⇒ Object

erDiagram relationship notation using crow's foot Format: left_cardinality--right_cardinality Cardinality markers:

|| = exactly one
o| = zero or one
}| = one or more
}o = zero or more


149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/rails_erd/diagram/mermaid.rb', line 149

def er_relation_notation(relationship)
  line = relationship.indirect? ? ".." : "--"

  # Left side (source cardinality - how many source entities relate to one destination)
  left = if relationship.many_to?
    relationship.source_optional? ? "o{" : "|{"
  else
    relationship.source_optional? ? "o|" : "||"
  end

  # Right side (destination cardinality - how many destination entities relate to one source)
  right = if relationship.to_many?
    relationship.destination_optional? ? "}o" : "}|"
  else
    relationship.destination_optional? ? "|o" : "||"
  end

  "#{left}#{line}#{right}"
end

#filenameObject



103
104
105
# File 'lib/rails_erd/diagram/mermaid.rb', line 103

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

#quote_entity_name(name) ⇒ Object

Quote entity names that contain special characters (like

for namespaces)

Mermaid erDiagram requires double quotes for names with special characters



133
134
135
136
137
138
139
140
# File 'lib/rails_erd/diagram/mermaid.rb', line 133

def quote_entity_name(name)
  name = name.to_s
  if name.include?("::")
    %("#{name}")
  else
    name
  end
end

#relation_arrow(relationship) ⇒ Object

classDiagram relationship arrows (legacy)



177
178
179
180
181
182
183
# File 'lib/rails_erd/diagram/mermaid.rb', line 177

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