module Sequel::Plugins::ClassTableInheritance::ClassMethods

Attributes

cti_base_model[R]

The parent/root/base model for this class table inheritance hierarchy. This is the only model in the hierarchy that load the class_table_inheritance plugin.

cti_columns[R]

Hash with table name symbol keys and arrays of column symbol values, giving the columns to update in each backing database table.

cti_key[R]

The column containing the class name as a string. Used to return instances of subclasses when calling the superclass's load method.

cti_model_map[R]

A hash with keys being values of the #cti_key column, and values being class name strings or symbols. Used if you don't want to store class names in the database.

cti_table_map[R]

A hash with class name symbol keys and table name symbol values. Specified with the :table_map option to the plugin, and used if the implicit naming is incorrect.

cti_tables[R]

An array of table symbols that back this model. The first is #cti_base_model table symbol, and the last is the current model table symbol.

Public Instance Methods

inherited(subclass) click to toggle source

Add the appropriate data structures to the subclass. Does not allow anonymous subclasses to be created, since they would not be mappable to a table.

Calls superclass method
# File lib/sequel/plugins/class_table_inheritance.rb, line 160
def inherited(subclass)
  cc = cti_columns
  ck = cti_key
  ct = cti_tables.dup
  ctm = cti_table_map.dup
  cbm = cti_base_model
  cmm = cti_model_map
  pk = primary_key
  ds = dataset
  table = nil
  columns = nil
  subclass.instance_eval do
    raise(Error, "cannot create anonymous subclass for model class using class_table_inheritance") if !(n = name) || n.empty?
    table = ctm[n.to_sym] || implicit_table_name
    columns = db.from(table).columns
    @cti_key = ck 
    @cti_tables = ct + [table]
    @cti_columns = cc.merge(table=>columns)
    @cti_table_map = ctm
    @cti_base_model = cbm
    @cti_model_map = cmm
    # Need to set dataset and columns before calling super so that
    # the main column accessor module is included in the class before any
    # plugin accessor modules (such as the lazy attributes accessor module).
    set_dataset(ds.join(table, pk=>pk).select_append(*(columns - [primary_key]).map{|c| Sequel.qualify(table, Sequel.identifier(c))}))
    set_columns(self.columns)
  end
  super
  subclass.instance_eval do
    set_dataset_cti_row_proc
    (columns - [cbm.primary_key]).each{|a| define_lazy_attribute_getter(a, :dataset=>dataset, :table=>table)}
    cti_tables.reverse.each do |t|
      db.schema(t).each{|k,v| db_schema[k] = v}
    end
  end
end
primary_key() click to toggle source

The primary key in the parent/base/root model, which should have a foreign key with the same name referencing it in each model subclass.

Calls superclass method
# File lib/sequel/plugins/class_table_inheritance.rb, line 199
def primary_key
  return super if self == cti_base_model
  cti_base_model.primary_key
end
table_name() click to toggle source

The table name for the current model class's main table (not used by any superclasses).

Calls superclass method
# File lib/sequel/plugins/class_table_inheritance.rb, line 206
def table_name
  self == cti_base_model ? super : cti_tables.last
end

Private Instance Methods

set_dataset_cti_row_proc() click to toggle source

Set the row_proc for the model's dataset appropriately based on the cti key and model map.

# File lib/sequel/plugins/class_table_inheritance.rb, line 220
def set_dataset_cti_row_proc
  m = method(:constantize)
  dataset.row_proc = if ck = cti_key
    if model_map = cti_model_map
      lambda do |r|
        mod = if name = model_map[r[ck]]
          m.call(name)
        else
          self
        end
        mod.call(r)
      end
    else
      lambda{|r| (m.call(r[ck]) rescue self).call(r)}
    end
  else
    self
  end
end
set_dataset_row_proc(ds) click to toggle source

If calling set_dataset manually, make sure to set the dataset row proc to one that handles inheritance correctly.

# File lib/sequel/plugins/class_table_inheritance.rb, line 214
def set_dataset_row_proc(ds)
  ds.row_proc = @dataset.row_proc if @dataset
end