Module: Torque::PostgreSQL::Inheritance::ClassMethods

Defined in:
lib/torque/postgresql/inheritance.rb

Instance Method Summary collapse

Instance Method Details

#base_classObject

For all main purposes, physical inherited classes should have base_class as their own



113
114
115
116
# File 'lib/torque/postgresql/inheritance.rb', line 113

def base_class
  return super unless physically_inherited?
  self
end

#casted_dependentsObject

Get the list of all ActiveRecord classes directly or indirectly associated by inheritance



80
81
82
83
84
# File 'lib/torque/postgresql/inheritance.rb', line 80

def casted_dependents
  @casted_dependents ||= inheritance_dependents.map do |table_name|
    [table_name, connection.schema_cache.lookup_model(table_name)]
  end.to_h
end

#compute_table_nameObject

Add an additional check to return the name of the table even when the class is inherited, but only if it is a physical inheritance



127
128
129
130
# File 'lib/torque/postgresql/inheritance.rb', line 127

def compute_table_name
  return super unless physically_inherited?
  decorated_table_name
end

#decorated_table_nameObject

Get the final decorated table, regardless of any special condition



100
101
102
103
104
105
106
107
108
109
# File 'lib/torque/postgresql/inheritance.rb', line 100

def decorated_table_name
  parent_class = try(:module_parent) || try(:parent)
  if parent_class < Base && !parent_class.abstract_class?
    contained = parent_class.table_name
    contained = contained.singularize if parent_class.pluralize_table_names
    contained += "_"
  end

  "#{full_table_name_prefix}#{contained}#{undecorated_table_name(name)}#{full_table_name_suffix}"
end

#inheritance_dependentsObject

Get the list of all tables directly or indirectly dependent of the current one



69
70
71
# File 'lib/torque/postgresql/inheritance.rb', line 69

def inheritance_dependents
  connection.schema_cache.associations(table_name) || []
end

#inheritance_mergeable_attributesObject

Get the list of attributes that can be merged while querying because they all have the same type



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/torque/postgresql/inheritance.rb', line 37

def inheritance_mergeable_attributes
  @inheritance_mergeable_attributes ||= begin
    base = inheritance_merged_attributes - attribute_names
    types = base.zip(base.size.times.map { [] }).to_h

    casted_dependents.values.each do |klass|
      klass.attribute_types.each do |column, type|
        types[column]&.push(type)
      end
    end

    result = types.select do
      |_, types| types.each_with_object(types.shift).all?(&:==)
    end.keys + attribute_names

    result.freeze
  end
end

#inheritance_merged_attributesObject

Get a full list of all attributes from a model and all its dependents



27
28
29
30
31
32
33
# File 'lib/torque/postgresql/inheritance.rb', line 27

def inheritance_merged_attributes
  @inheritance_merged_attributes ||= begin
    list = attribute_names
    list += casted_dependents.values.map(&:attribute_names)
    list.flatten.uniq.freeze
  end
end

#physically_inheritances?Boolean

Check whether the model’s table has directly or indirectly dependents

Returns:

  • (Boolean)


74
75
76
# File 'lib/torque/postgresql/inheritance.rb', line 74

def physically_inheritances?
  inheritance_dependents.present?
end

#physically_inherited?Boolean

Check if the model’s table depends on any inheritance

Returns:

  • (Boolean)


57
58
59
60
61
62
63
64
65
# File 'lib/torque/postgresql/inheritance.rb', line 57

def physically_inherited?
  return @physically_inherited if defined?(@physically_inherited)

  @physically_inherited = connection.schema_cache.dependencies(
    defined?(@table_name) ? @table_name : decorated_table_name,
  ).present?
rescue ActiveRecord::ConnectionNotEstablished
  false
end

#primary_keyObject

Primary key is one exception when getting information about the class, it must returns the superclass PK



120
121
122
123
# File 'lib/torque/postgresql/inheritance.rb', line 120

def primary_key
  return super unless physically_inherited?
  superclass.primary_key
end

#raise_unable_to_cast(record_class_value) ⇒ Object

Raises an error message saying that the giver record class was not able to be casted since the model was not identified

Raises:



134
135
136
137
138
139
140
141
# File 'lib/torque/postgresql/inheritance.rb', line 134

def raise_unable_to_cast(record_class_value)
  raise InheritanceError.new(<<~MSG.squish)
    An record was not able to be casted to type '#{record_class_value}'.
    If this table name doesn't represent a guessable model,
    please use 'Torque::PostgreSQL.conf.irregular_models =
    { '#{record_class_value}' => 'ModelName' }'.
  MSG
end

#reset_table_nameObject

Manually set the model name associated with tables name in order to facilitates the identification of inherited records



88
89
90
91
92
93
94
95
96
97
# File 'lib/torque/postgresql/inheritance.rb', line 88

def reset_table_name
  table = super

  adapter = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
  if Torque::PostgreSQL.config.eager_load && connection.is_a?(adapter)
    connection.schema_cache.add_model_name(table, self)
  end

  table
end