From 0399fc7351d5d59d78af77130d4e1e4e7a6b8b0d Mon Sep 17 00:00:00 2001 From: Sam Bostock Date: Thu, 16 Nov 2017 17:20:46 -0500 Subject: Expand AR::Base.abstract_class documentation The previous documentation is somewhat unclear about the use case for an abstract ActiveRecord class. This clears it up by highlighting the following points: - table_name is not derived from the abstract class' name - type is not derived on direct descendants of the abstract class - validations, not abstract_class, should be used to specify whether the parent model can be instantiated or not --- activerecord/lib/active_record/inheritance.rb | 46 +++++++++++++++++++++------ 1 file changed, 36 insertions(+), 10 deletions(-) (limited to 'activerecord/lib/active_record/inheritance.rb') diff --git a/activerecord/lib/active_record/inheritance.rb b/activerecord/lib/active_record/inheritance.rb index f3fe610c09..77cfb36b25 100644 --- a/activerecord/lib/active_record/inheritance.rb +++ b/activerecord/lib/active_record/inheritance.rb @@ -104,21 +104,47 @@ module ActiveRecord end end - # Set this to true if this is an abstract class (see abstract_class?). - # If you are using inheritance with ActiveRecord and don't want child classes - # to utilize the implied STI table name of the parent class, this will need to be true. - # For example, given the following: + # Set this to +true+ if this is an abstract class (see + # abstract_class?). + # If you are using inheritance with Active Record and don't want a class + # to be considered as part of the STI hierarchy, you must set this to + # true. + # +ApplicationRecord+, for example, is generated as an abstract class. # - # class SuperClass < ActiveRecord::Base + # Consider the following default behaviour: + # + # Shape = Class.new(ActiveRecord::Base) + # Polygon = Class.new(Shape) + # Square = Class.new(Polygon) + # + # Shape.table_name # => "shapes" + # Polygon.table_name # => "shapes" + # Square.table_name # => "shapes" + # Shape.create! # => # + # Polygon.create! # => # + # Square.create! # => # + # + # However, when using abstract_class, +Shape+ is omitted from + # the hierarchy: + # + # class Shape < ActiveRecord::Base # self.abstract_class = true # end - # class Child < SuperClass - # self.table_name = 'the_table_i_really_want' - # end - # + # Polygon = Class.new(Shape) + # Square = Class.new(Polygon) # - # self.abstract_class = true is required to make Child<.find,.create, or any Arel method> use the_table_i_really_want instead of a table called super_classes + # Shape.table_name # => nil + # Polygon.table_name # => "polygons" + # Square.table_name # => "polygons" + # Shape.create! # => NotImplementedError: Shape is an abstract class and cannot be instantiated. + # Polygon.create! # => # + # Square.create! # => # # + # Note that in the above example, to disallow the creation of a plain + # +Polygon+, you should use validates :type, presence: true, + # instead of setting it as an abstract class. This way, +Polygon+ will + # stay in the hierarchy, and Active Record will continue to correctly + # derive the table name. attr_accessor :abstract_class # Returns whether this class is an abstract class or not. -- cgit v1.2.3