module ActiveRecord::MTI::Inheritance::ClassMethods

Public Instance Methods

has_tableoid_column?() click to toggle source
# File lib/active_record/mti/inheritance.rb, line 15
def has_tableoid_column?
  tableoid_column != false
end
inherited(subclass) click to toggle source
Calls superclass method
# File lib/active_record/mti/inheritance.rb, line 19
def inherited(subclass)
  super
  subclass.using_multi_table_inheritance?
end
uses_mti(*args) click to toggle source
# File lib/active_record/mti/inheritance.rb, line 24
def uses_mti(*args)
  warn "DEPRECATED - `uses_mti` is no longer needed (nor has any effect)"
end
using_multi_table_inheritance?() click to toggle source
# File lib/active_record/mti/inheritance.rb, line 28
def using_multi_table_inheritance?
  mti = ActiveRecord::MTI::Registry.tableoid?(self)
  return (mti != false) unless mti == nil

  if (mti = check_inheritance_of(@table_name))
    if (self != base_class && self.table_name == base_class.table_name)
      mti = false
    else
      mti = detect_tableoid(table_name)
    end
  end

  ActiveRecord::MTI::Registry[self] = mti

  descendants.each do |d|
    d.using_multi_table_inheritance?
  end

  return mti && mti != false
end

Private Instance Methods

add_tableoid_column() click to toggle source
# File lib/active_record/mti/inheritance.rb, line 115
def add_tableoid_column
  if self.respond_to? :attribute
    self.attribute :tableoid, ActiveRecord::MTI.oid_class.new
  else
    new_column = ActiveRecord::ConnectionAdapters::PostgreSQLColumn.new('tableoid', nil, ActiveRecord::MTI.oid_class.new, "oid", false)
    columns.unshift new_column
    columns_hash['tableoid'] = new_column
  end
end
check_inheritance_of(table_name, table_schema = 'public') click to toggle source
# File lib/active_record/mti/inheritance.rb, line 51
        def check_inheritance_of(table_name, table_schema = 'public')
          ActiveRecord::MTI.logger.debug("Trying to check inheritance of table with no table name (#{self})") and return nil unless table_name
          ActiveRecord::MTI.logger.debug "Checking inheritance for #{table_schema}.#{table_name}"

          result = connection.execute <<-SQL
            SELECT EXISTS (
              SELECT 1
                FROM pg_catalog.pg_inherits       AS i
                  JOIN information_schema.tables  AS t ON t.table_schema = '#{table_schema}' AND t.table_name = '#{table_name}'
                  LEFT JOIN pg_catalog.pg_rewrite AS r ON r.ev_class     = t.table_name::regclass::oid
                  LEFT JOIN pg_catalog.pg_depend  AS d ON d.objid        = r.oid
                  LEFT JOIN pg_catalog.pg_class   AS c ON c.oid          = d.refobjid
                WHERE i.inhrelid  = COALESCE(c.relname, t.table_name)::regclass::oid
                  OR i.inhparent = COALESCE(c.relname, t.table_name)::regclass::oid
            ) AS uses_inheritance;
          SQL

          return ActiveRecord::MTI.testify(result.try(:first)['uses_inheritance']) == true
        end
detect_tableoid(table_name, table_schema = 'public') click to toggle source
# File lib/active_record/mti/inheritance.rb, line 71
        def detect_tableoid(table_name, table_schema = 'public')

          tableoid_query = connection.execute(<<-SQL
            SELECT 1 AS has_tableoid_column, t.table_name::regclass::oid as tableoid
              FROM   pg_catalog.pg_attribute
              JOIN   information_schema.tables t ON t.table_schema = '#{table_schema}' AND t.table_name = '#{table_name}'
              WHERE  attrelid = t.table_name::regclass
              AND    attname  = 'tableoid'
              AND    NOT attisdropped;
          SQL
          ).first

          tableoid = tableoid_query.try(:[], 'tableoid') || false
          @tableoid_column = ActiveRecord::MTI.testify(tableoid_query.try(:[], 'has_tableoid_column'))

          if (has_tableoid_column?)
            ActiveRecord::MTI.logger.debug "#{table_schema}.#{table_name} has tableoid column! (#{tableoid})"
            add_tableoid_column
            @mti_type_column = arel_table[:tableoid]
          else
            @mti_type_column = nil
          end

          tableoid
        end
discriminate_class_for_record(record) click to toggle source

Called by instantiate to decide which class to use for a new record instance. For single-table inheritance, we check the record for a type column and return the corresponding class.

Calls superclass method
# File lib/active_record/mti/inheritance.rb, line 100
def discriminate_class_for_record(record)
  if using_multi_table_inheritance?
    ActiveRecord::MTI::Registry.find_mti_class(record['tableoid']) || self
  else
    super
  end
end
type_condition(table = arel_table) click to toggle source

Type condition only applies if it's STI, otherwise it's done for free by querying the inherited table in MTI

Calls superclass method
# File lib/active_record/mti/inheritance.rb, line 110
def type_condition(table = arel_table)
  return nil if using_multi_table_inheritance?
  super
end