module Sequel::Plugins::ClassTableInheritance::ClassMethods
Attributes
An array of columns that may be duplicated in sub-classes. The primary key column is always allowed to be duplicated
The dataset that table instance datasets are based on. Used for database modifications
An array of each model in the inheritance hierarchy that is backed by a new table.
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).
An array of column symbols for the backing database table, giving the columns to update in each backing database table.
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.
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
The name of the most recently joined table.
# File lib/sequel/plugins/class_table_inheritance.rb 291 def cti_table_name 292 cti_tables.last 293 end
Freeze CTI information when freezing model class.
# 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
The model class for the given key value.
# File lib/sequel/plugins/class_table_inheritance.rb 296 def sti_class_from_key(key) 297 sti_class(sti_model_map[key]) 298 end
The table name for the current model class’s main table.
# File lib/sequel/plugins/class_table_inheritance.rb 282 def table_name 283 if cti_tables && cti_tables.length > 1 284 @cti_alias 285 else 286 super 287 end 288 end
Private Instance Methods
# File lib/sequel/plugins/class_table_inheritance.rb 302 def inherited(subclass) 303 ds = sti_dataset 304 305 # Prevent inherited in model/base.rb from setting the dataset 306 subclass.instance_exec { @dataset = nil } 307 308 super 309 310 # Set table if this is a class table inheritance 311 table = nil 312 columns = nil 313 if n = subclass.name 314 if table = cti_table_map[n.to_sym] 315 columns = db.schema(table).map(&:first) 316 else 317 table = if cti_qualify_tables && (schema = dataset.schema_and_table(cti_table_name).first) 318 SQL::QualifiedIdentifier.new(schema, subclass.implicit_table_name) 319 else 320 subclass.implicit_table_name 321 end 322 columns = check_non_connection_error(false){db.schema(table) && db.schema(table).map(&:first)} 323 table = nil if !columns || columns.empty? 324 end 325 end 326 table = nil if table && (table == cti_table_name) 327 328 return unless table 329 330 pk = primary_key 331 subclass.instance_exec do 332 if cti_tables.length == 1 333 ds = ds.select(*self.columns.map{|cc| Sequel.qualify(cti_table_name, Sequel.identifier(cc))}) 334 end 335 ds.send(:columns=, self.columns) 336 cols = (columns - [pk]) - cti_ignore_subclass_columns 337 dup_cols = cols & ds.columns 338 unless dup_cols.empty? 339 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" 340 end 341 sel_app = cols.map{|cc| Sequel.qualify(table, Sequel.identifier(cc))} 342 @sti_dataset = ds = ds.join(table, pk=>pk).select_append(*sel_app) 343 344 ds = ds.from_self(:alias=>@cti_alias) 345 ds.send(:columns=, self.columns + cols) 346 347 set_dataset(ds) 348 set_columns(self.columns) 349 @dataset = @dataset.with_row_proc(lambda{|r| subclass.sti_load(r)}) 350 cols.each{|a| define_lazy_attribute_getter(a, :dataset=>dataset, :table=>@cti_alias)} 351 352 @cti_models += [self] 353 @cti_tables += [table] 354 @cti_table_columns = columns 355 @cti_instance_dataset = db.from(table) 356 357 cti_tables.reverse_each do |ct| 358 db.schema(ct).each{|sk,v| db_schema[sk] = v} 359 end 360 setup_auto_validations if respond_to?(:setup_auto_validations, true) 361 end 362 end
If using a subquery for class table inheritance, also use a subquery when setting subclass dataset.
# 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