Module: Metasploit::Credential::EntityRelationshipDiagram
- Defined in:
- lib/metasploit/credential/entity_relationship_diagram.rb
Constant Summary collapse
- ATTRIBUTES =
Enable all attributes
[ :content, :foreign_keys, :primary_keys, :timestamps ]
- INDIRECT =
Only show direct relationships since the ERD is for use with SQL and there is no need to show has_many :through for those purposes.
false- INHERITANCE =
Show inheritance for Single-Table Inheritance
true- NOTATION =
Use crowsfoot notation since its what we use for manually drawn diagrams.
:crowsfoot- DEFAULT_OPTIONS =
Default options for Diagram.
{ attributes: ATTRIBUTES, indirect: INDIRECT, inheritance: INHERITANCE, notation: NOTATION }
Class Method Summary collapse
-
.cluster(*classes) ⇒ Set<Class<ActiveRecord::Base>>
Cluster of classes that are reachable through belongs_to from
classes. -
.cluster_by_class ⇒ Hash{Class<ActiveRecord::Base> => Set<Class<ActiveRecord::Base>>}
All clusters of classes that are reachable through belongs_to from each ActiveRecord::Base descendant.
-
.create(options = {}) ⇒ String
Creates Graphviz diagram.
-
.domain ⇒ RailsERD::Domain
Domain containing all models in this gem.
-
.maximal_clusters ⇒ Array<Set<Class<ActiveRecord::Base>>>
Set of largest clusters from EntityRelationshipDiagram.cluster_by_class.
-
.polymorphic_classes(belongs_to_reflection) ⇒ Array<ActiveRecord::Base>
Calculates the target classes for a polymorphic
belongs_to.
Class Method Details
.cluster(*classes) ⇒ Set<Class<ActiveRecord::Base>>
Cluster of classes that are reachable through belongs_to from classes.
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/metasploit/credential/entity_relationship_diagram.rb', line 61 def self.cluster(*classes) class_queue = classes.dup visited_class_set = Set.new until class_queue.empty? klass = class_queue.pop # add immediately to visited set in case there are recursive associations visited_class_set.add klass # only iterate belongs_to as they need to be included so that foreign keys aren't let dangling in the ERD. reflections = klass.reflect_on_all_associations(:belongs_to) reflections.each do |reflection| if reflection.[:polymorphic] target_klasses = polymorphic_classes(reflection) else target_klasses = [reflection.klass] end target_klasses.each do |target_klass| unless visited_class_set.include? target_klass class_queue << target_klass end end end end visited_class_set end |
.cluster_by_class ⇒ Hash{Class<ActiveRecord::Base> => Set<Class<ActiveRecord::Base>>}
All clusters of classes that are reachable through belongs_to from each ActiveRecord::Base descendant
43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/metasploit/credential/entity_relationship_diagram.rb', line 43 def self.cluster_by_class cluster_by_class = {} Metasploit::Credential::Engine.instance.eager_load! ActiveRecord::Base.descendants.each do |klass| klass_cluster = cluster(klass) cluster_by_class[klass] = klass_cluster end cluster_by_class end |
.create(options = {}) ⇒ String
Creates Graphviz diagram.
98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/metasploit/credential/entity_relationship_diagram.rb', line 98 def self.create(={}) domain = [:domain] domain ||= self.domain = .except(:domain) = DEFAULT_OPTIONS.merge() require 'rails_erd/domain' diagram = RailsERD::Diagram::Graphviz.new(domain, ) path = diagram.create path end |
.domain ⇒ RailsERD::Domain
Domain containing all models in this gem.
116 117 118 119 120 121 |
# File 'lib/metasploit/credential/entity_relationship_diagram.rb', line 116 def self.domain require_models require 'rails_erd/domain' RailsERD::Domain.generate end |
.maximal_clusters ⇒ Array<Set<Class<ActiveRecord::Base>>>
Set of largest clusters from cluster_by_class.
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/metasploit/credential/entity_relationship_diagram.rb', line 126 def self.maximal_clusters clusters = cluster_by_class.values unique_clusters = clusters.uniq maximal_clusters = unique_clusters.dup cluster_queue = unique_clusters.dup until cluster_queue.empty? cluster = cluster_queue.pop proper_subset = false maximal_clusters.each do |maximal_cluster| if cluster.proper_subset? maximal_cluster proper_subset = true break end end if proper_subset maximal_clusters.delete(cluster) end end maximal_clusters end |
.polymorphic_classes(belongs_to_reflection) ⇒ Array<ActiveRecord::Base>
Calculates the target classes for a polymorphic belongs_to.
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/metasploit/credential/entity_relationship_diagram.rb', line 156 def self.polymorphic_classes(belongs_to_reflection) name = belongs_to_reflection.name ActiveRecord::Base.descendants.each_with_object([]) { |descendant, target_classes| has_many_reflections = descendant.reflect_on_all_associations(:has_many) has_many_reflections.each do |has_many_reflection| as = has_many_reflection.[:as] if as == name target_classes << descendant end end } end |