module Sequel::Plugins::SingleTableInheritance::ClassMethods
Attributes
The base dataset for STI, to which filters are added to get only the models for the specific STI subclass.
The column name holding the STI key for this model
Array holding keys for all subclasses of this class, used for the dataset filter in subclasses. Nil in the main class.
A proc which returns the value to use for new instances. This defaults to a lookup in the key map.
A hash/proc with class keys and column value values, mapping the class to a particular value given to the sti_key column. Used to set the column value when creating objects, and for the filter when retrieving objects in subclasses.
A hash/proc with column value keys and class values, mapping the value of the sti_key column to the appropriate class to use.
Public Instance Methods
Source
# File lib/sequel/plugins/single_table_inheritance.rb 164 def freeze 165 @sti_key_array.freeze if @sti_key_array 166 @sti_key_map.freeze if @sti_key_map.is_a?(Hash) 167 @sti_model_map.freeze if @sti_model_map.is_a?(Hash) 168 169 super 170 end
Freeze STI information when freezing model class. Note that because of how STI works, you should not freeze an STI subclass until after all subclasses of it have been created.
Source
# File lib/sequel/plugins/single_table_inheritance.rb 179 def sti_class_from_sti_key(key) 180 sti_class(sti_model_map[key]) 181 end
Return the sti class based on one of the keys from sti_model_map.
Source
# File lib/sequel/plugins/single_table_inheritance.rb 174 def sti_load(r) 175 sti_class_from_sti_key(r[sti_key]).call(r) 176 end
Return an instance of the class specified by sti_key, used by the row_proc.
Source
# File lib/sequel/plugins/single_table_inheritance.rb 185 def sti_subclass_added(key) 186 if sti_key_array 187 key_array = Array(key) 188 Sequel.synchronize{sti_key_array.push(*key_array)} 189 superclass.sti_subclass_added(key) 190 end 191 end
Make sure that all subclasses of the parent class correctly include keys for all of their descendant classes.
Private Instance Methods
Source
# File lib/sequel/plugins/single_table_inheritance.rb 197 def dataset_extend(mod, opts=OPTS) 198 @sti_dataset = @sti_dataset.with_extend(mod) 199 super 200 end
Extend the sti dataset with the module when extending the main dataset.
Source
# File lib/sequel/plugins/single_table_inheritance.rb 204 def inherited(subclass) 205 super 206 key = Array(sti_key_map[subclass]).dup 207 sti_subclass_added(key) 208 rp = dataset.row_proc 209 subclass.set_dataset(sti_subclass_dataset(key), :inherited=>true) 210 subclass.instance_exec do 211 @dataset = @dataset.with_row_proc(rp) 212 @sti_key_array = key 213 self.simple_table = nil 214 end 215 end
Copy the necessary attributes to the subclasses, and filter the subclass’s dataset based on the sti_key_map entry for the class.
Source
# File lib/sequel/plugins/single_table_inheritance.rb 219 def set_dataset_row_proc(ds) 220 if @dataset 221 ds.with_row_proc(@dataset.row_proc) 222 else 223 super 224 end 225 end
If calling set_dataset manually, make sure to set the dataset row proc to one that handles inheritance correctly.
Source
# File lib/sequel/plugins/single_table_inheritance.rb 234 def sti_class(v) 235 case v 236 when String, Symbol 237 begin 238 klass = constantize(v) 239 if Class === klass && @sti_root_class >= klass 240 klass 241 else 242 @sti_root_class 243 end 244 rescue 245 self 246 end 247 when nil 248 self 249 when Class 250 v 251 else 252 raise(Error, "Invalid class type used: #{v.inspect}") 253 end 254 end
Return a class object. If a class is given, return it directly. Treat strings and symbols as class names. If nil is given or an invalid class name string or symbol is used, return self. If the class is valid but is not a subclass of the class that loaded the single_table_inheritance plugin, use the class that loaded the plugin. Raise an error for other types.
Source
# File lib/sequel/plugins/single_table_inheritance.rb 258 def sti_subclass_dataset(key) 259 sti_dataset.where(SQL::QualifiedIdentifier.new(sti_dataset.first_source_alias, sti_key)=>Sequel.delay{Sequel.synchronize{key}}) 260 end
Use the given dataset for the subclass, with key being the allowed values for the sti_kind field.