Module: ActiveRecord::Inheritance
Relationships & Source Files | |
Namespace Children | |
Modules:
| |
Extension / Inclusion / Inheritance Descendants | |
Included In:
| |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
self,
::ActiveSupport::Concern
|
|
Defined in: | activerecord/lib/active_record/inheritance.rb |
Overview
Single table inheritance
Active Record allows inheritance by storing the name of the class in a column that by default is named “type” (can be changed by overwriting Base.inheritance_column). This means that an inheritance looking like this:
class Company < ActiveRecord::Base; end
class Firm < Company; end
class Client < Company; end
class PriorityClient < Client; end
When you do Firm.create(name: "37signals")
, this record will be saved in the companies table with type = “Firm”. You can then fetch this row again using Company.where(name: '37signals').first
and it will return a Firm object.
Be aware that because the type column is an attribute on the record every new subclass will instantly be marked as dirty and the type column will be included in the list of changed attributes on the record. This is different from non Single Table Inheritance(STI) classes:
Company.new.changed? # => false
Firm.new.changed? # => true
Firm.new.changes # => {"type"=>["","Firm"]}
If you don’t have a type column defined in your table, single-table inheritance won’t be triggered. In that case, it’ll work just like normal subclasses with no special magic for differentiating between them or reloading the right type with find.
Note, all the attributes for all the cases are kept in the same table. Read more:
Class Method Summary
::ActiveSupport::Concern
- Extended
class_methods | Define class methods from given block. |
included | Evaluate given block in context of base class, so that you can write class macros here. |
prepended | Evaluate given block in context of base class, so that you can write class macros here. |
append_features, prepend_features |
Instance Method Summary
- #initialize_dup(other)
-
#ensure_proper_type
private
Sets the attribute used for single table inheritance to this class name if this is not the
Base
descendant. - #initialize_internals_callback private
DSL Calls
included
[ GitHub ]42 43 44 45 46 47 48 49 50
# File 'activerecord/lib/active_record/inheritance.rb', line 42
included do class_attribute :store_full_class_name, instance_writer: false, default: true # Determines whether to store the full constant name including namespace when using STI. # This is true, by default. class_attribute :store_full_sti_class, instance_writer: false, default: true set_base_class end
Instance Method Details
#ensure_proper_type (private)
Sets the attribute used for single table inheritance to this class name if this is not the Base
descendant. Considering the hierarchy Reply < Message < Base
, this makes it possible to do Reply.new
without having to set Reply[Reply.inheritance_column] = "Reply"
yourself. No such attribute would be set for objects of the Message class in that example.
# File 'activerecord/lib/active_record/inheritance.rb', line 359
def ensure_proper_type klass = self.class if klass.finder_needs_type_condition? _write_attribute(klass.inheritance_column, klass.sti_name) end end
#initialize_dup(other)
[ GitHub ]# File 'activerecord/lib/active_record/inheritance.rb', line 343
def initialize_dup(other) super ensure_proper_type end
#initialize_internals_callback (private)
[ GitHub ]# File 'activerecord/lib/active_record/inheritance.rb', line 349
def initialize_internals_callback super ensure_proper_type end