Class: Snapbot::Reflector

Inherits:
Object
  • Object
show all
Defined in:
lib/snapbot/reflector.rb,
lib/snapbot/reflector/relationship.rb

Overview

Reflect models and instances in a way that’s useful for generating a diagram

Defined Under Namespace

Classes: Relationship

Constant Summary collapse

ACTIVERECORD_IGNORE =
[
  /^Schema$/,
  /^HABTM_/,
  /^ActiveRecord::InternalMetadata$/,
  /^ActiveRecord::SchemaMigration$/
].freeze

Instance Method Summary collapse

Instance Method Details

#activerecord_ignore?(klass) ⇒ Boolean

Returns:

  • (Boolean)


28
29
30
# File 'lib/snapbot/reflector.rb', line 28

def activerecord_ignore?(klass)
  ACTIVERECORD_IGNORE.any? { |r| klass.name =~ r } || klass.abstract_class
end

#add_relationships(instance, set) ⇒ Object



45
46
47
48
49
50
51
52
53
54
# File 'lib/snapbot/reflector.rb', line 45

def add_relationships(instance, set)
  reflect_associations(instance).each do |association|
    next unless valid_association?(association) # Skip POROs

    records = Array(instance.send(association.name)).compact
    records.each do |record|
      set.add(Relationship.new(instance_name(instance), instance_name(record)))
    end
  end
end

#attributes(instance) ⇒ Object



64
65
66
# File 'lib/snapbot/reflector.rb', line 64

def attributes(instance)
  instance.attributes.to_h.transform_values { |v| v.is_a?(Hash) ? escape_hash(v) : v }
end

#base_activerecord_classObject



9
10
11
# File 'lib/snapbot/reflector.rb', line 9

def base_activerecord_class
  defined?(ApplicationRecord) ? ApplicationRecord : ActiveRecord::Base
end

#instancesObject



32
33
34
35
36
# File 'lib/snapbot/reflector.rb', line 32

def instances
  @instances ||= models.each_with_object([]) do |klass, array|
    array << klass.all
  end.flatten
end

#models(only_with_records: true) ⇒ Object



13
14
15
16
17
18
19
20
# File 'lib/snapbot/reflector.rb', line 13

def models(only_with_records: true)
  @models ||= begin
    Rails.application.eager_load! if defined?(Rails)
    base_activerecord_class.descendants.reject do |c|
      activerecord_ignore?(c) || (only_with_records && c.count.zero?)
    end
  end
end

#reflect_associations(instance) ⇒ Object



56
57
58
59
60
61
62
# File 'lib/snapbot/reflector.rb', line 56

def reflect_associations(instance)
  (
    instance.class.reflect_on_all_associations(:has_many).reject { |a| a.name == :schemas } +
      instance.class.reflect_on_all_associations(:has_one) +
      instance.class.reflect_on_all_associations(:has_and_belongs_to_many)
  ).flatten
end

#relationshipsObject

A Set of relationships to other identified entities



39
40
41
42
43
# File 'lib/snapbot/reflector.rb', line 39

def relationships
  @relationships ||= instances.each_with_object(Set.new) do |instance, set|
    add_relationships(instance, set)
  end
end