module Sequel::Plugins::ClassTableInheritance::ClassMethods

Attributes

cti_ignore_subclass_columns[R]

An array of columns that may be duplicated in sub-classes. The primary key column is always allowed to be duplicated

cti_instance_dataset[R]

The dataset that table instance datasets are based on. Used for database modifications

cti_models[R]

An array of each model in the inheritance hierarchy that is backed by a new table.

cti_qualify_tables[R]

A boolean indicating whether or not to automatically qualify tables backing subclasses with the same qualifier as their superclass, if the superclass is qualified. Specified with the :qualify_tables option to the plugin and only applied to automatically determined table names (not to the :table_map option).

cti_table_columns[R]

An array of column symbols for the backing database table, giving the columns to update in each backing database table.

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 should be used if the implicit naming is incorrect.

cti_tables[R]

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

Public Instance Methods

cti_table_name() click to toggle source

The name of the most recently joined table.

    # File lib/sequel/plugins/class_table_inheritance.rb
353 def cti_table_name
354   cti_tables ? cti_tables.last : dataset.first_source_alias
355 end
freeze() click to toggle source

Freeze CTI information when freezing model class.

Calls superclass method
    # File lib/sequel/plugins/class_table_inheritance.rb
269 def freeze
270   @cti_models.freeze
271   @cti_tables.freeze
272   @cti_table_columns.freeze
273   @cti_table_map.freeze
274   @cti_ignore_subclass_columns.freeze
275 
276   super
277 end
inherited(subclass) click to toggle source
Calls superclass method
    # File lib/sequel/plugins/class_table_inheritance.rb
281 def inherited(subclass)
282   ds = sti_dataset
283 
284   # Prevent inherited in model/base.rb from setting the dataset
285   subclass.instance_exec { @dataset = nil }
286 
287   super
288 
289   # Set table if this is a class table inheritance
290   table = nil
291   columns = nil
292   if (n = subclass.name) && !n.empty?
293     if table = cti_table_map[n.to_sym]
294       columns = db.schema(table).map(&:first)
295     else
296       table = if cti_qualify_tables && (schema = dataset.schema_and_table(cti_table_name).first)
297         SQL::QualifiedIdentifier.new(schema, subclass.implicit_table_name)
298       else
299         subclass.implicit_table_name
300       end
301       columns = check_non_connection_error(false){db.schema(table) && db.schema(table).map(&:first)}
302       table = nil if !columns || columns.empty?
303     end
304   end
305   table = nil if table && (table == cti_table_name)
306 
307   return unless table
308 
309   pk = primary_key
310   subclass.instance_exec do
311     if cti_tables.length == 1
312       ds = ds.select(*self.columns.map{|cc| Sequel.qualify(cti_table_name, Sequel.identifier(cc))})
313     end
314     ds.send(:columns=, self.columns)
315     cols = (columns - [pk]) - cti_ignore_subclass_columns
316     dup_cols = cols & ds.columns
317     unless dup_cols.empty?
318       raise Error, "class_table_inheritance with duplicate column names (other than the primary key column) is not supported, make sure tables have unique column names (duplicate columns: #{dup_cols}). If this is desired, specify these columns in the :ignore_subclass_columns option when initializing the plugin"
319     end
320     sel_app = cols.map{|cc| Sequel.qualify(table, Sequel.identifier(cc))}
321     @sti_dataset = ds = ds.join(table, pk=>pk).select_append(*sel_app)
322 
323     ds = ds.from_self(:alias=>@cti_alias)
324     ds.send(:columns=, self.columns + cols)
325 
326     set_dataset(ds)
327     set_columns(self.columns)
328     @dataset = @dataset.with_row_proc(lambda{|r| subclass.sti_load(r)})
329     cols.each{|a| define_lazy_attribute_getter(a, :dataset=>dataset, :table=>@cti_alias)}
330 
331     @cti_models += [self]
332     @cti_tables += [table]
333     @cti_table_columns = columns
334     @cti_instance_dataset = db.from(table)
335 
336     cti_tables.reverse_each do |ct|
337       db.schema(ct).each{|sk,v| db_schema[sk] = v}
338     end
339     setup_auto_validations if respond_to?(:setup_auto_validations, true)
340   end
341 end
sti_class_from_key(key) click to toggle source

The model class for the given key value.

    # File lib/sequel/plugins/class_table_inheritance.rb
358 def sti_class_from_key(key)
359   sti_class(sti_model_map[key])
360 end
table_name() click to toggle source

The table name for the current model class's main table.

Calls superclass method
    # File lib/sequel/plugins/class_table_inheritance.rb
344 def table_name
345   if cti_tables && cti_tables.length > 1
346     @cti_alias
347   else
348     super
349   end
350 end

Private Instance Methods

sti_subclass_dataset(key) click to toggle source

If using a subquery for class table inheritance, also use a subquery when setting subclass dataset.

Calls superclass method
    # File lib/sequel/plugins/class_table_inheritance.rb
366 def sti_subclass_dataset(key)
367   ds = super
368   if cti_models[0] != self
369     ds = ds.from_self(:alias=>@cti_alias)
370   end
371   ds
372 end