Module | Sequel::Plugins::SingleTableInheritance
In: | lib/sequel/plugins/single_table_inheritance.rb

The single_table_inheritance plugin allows storing all objects in the same class hierarchy in the same table. It makes it so subclasses of this model only load rows related to the subclass, and when you retrieve rows from the main class, you get instances of the subclasses (if the rows should use the subclasses‘s class).

By default, the plugin assumes that the `sti_key` column (the first argument to the plugin) holds the class name as a string. However, you can override this by using the `:model_map` option and/or the `:key_map` option.

You should only load this plugin in the parent class, not in the subclasses.

You shouldn‘t call set_dataset in the model after applying this plugin, otherwise subclasses might use the wrong dataset. You should make sure this plugin is loaded before the subclasses. Note that since you need to load the plugin before the subclasses are created, you can‘t use direct class references in the plugin class. You should specify subclasses in the plugin call using class name strings or symbols, see usage below.

Usage:

      # Use the default of storing the class name in the sti_key
      # column (:kind in this case)
      Employee.plugin :single_table_inheritance, :kind

      # Using integers to store the class type, with a :model_map hash
      # and an sti_key of :type
      Employee.plugin :single_table_inheritance, :type,
        :model_map=>{1=>:Staff, 2=>:Manager}

      # Using non-class name strings
      Employee.plugin :single_table_inheritance, :type,
        :model_map=>{'line staff'=>:Staff, 'supervisor'=>:Manager}

      # Using custom procs, with :model_map taking column values
      # and yielding either a class, string, symbol, or nil,
      # and :key_map taking a class object and returning the column
      # value to use
      Employee.plugin :single_table_inheritance, :type,
        :model_map=>proc{|v| v.reverse},
        :key_map=>proc{|klass| klass.name.reverse}

One minor issue to note is that if you specify the `:key_map` option as a hash, instead of having it inferred from the `:model_map`, you should only use class name strings as keys, you should not use symbols as keys.

### Methods

configure

### Classes and Modules

Module Sequel::Plugins::SingleTableInheritance::ClassMethods
Module Sequel::Plugins::SingleTableInheritance::InstanceMethods

### Public Class methods

configure(model, key, opts={})

Setup the necessary STI variables, see the module RDoc for SingleTableInheritance

[Source]

        # File lib/sequel/plugins/single_table_inheritance.rb, line 52
    52:       def self.configure(model, key, opts={})
    53:         model.instance_eval do
    54:           @sti_key_array = nil
    55:           @sti_key = key
    56:           @sti_dataset = dataset
    57:           @sti_model_map = opts[:model_map] || lambda{|v| v if v && v != ''}
    58:           @sti_key_map = if km = opts[:key_map]
    59:             if km.is_a?(Hash)
    60:               h = Hash.new{|h,k| h[k.to_s] unless k.is_a?(String)}
    61:               h.merge!(km)
    62:             else
    63:               km
    64:             end
    65:           elsif sti_model_map.is_a?(Hash)
    66:             h = Hash.new{|h,k| h[k.to_s] unless k.is_a?(String)}
    67:             sti_model_map.each do |k,v|
    68:               h[v.to_s] = k
    69:             end
    70:             h
    71:           else
    72:             lambda{|klass| klass.name.to_s}
    73:           end
    74:           dataset.row_proc = lambda{|r| model.sti_load(r)}
    75:         end
    76:       end

[Validate]