aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/inheritance.rb46
-rw-r--r--activerecord/test/cases/dirty_test.rb6
2 files changed, 37 insertions, 15 deletions
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 <tt>abstract_class?</tt>).
- # 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
+ # <tt>abstract_class?</tt>).
+ # 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! # => #<Shape id: 1, type: nil>
+ # Polygon.create! # => #<Polygon id: 2, type: "Polygon">
+ # Square.create! # => #<Square id: 3, type: "Square">
+ #
+ # However, when using <tt>abstract_class</tt>, +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)
#
- # <tt>self.abstract_class = true</tt> is required to make <tt>Child<.find,.create, or any Arel method></tt> use <tt>the_table_i_really_want</tt> instead of a table called <tt>super_classes</tt>
+ # 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! # => #<Polygon id: 1, type: nil>
+ # Square.create! # => #<Square id: 2, type: "Square">
#
+ # Note that in the above example, to disallow the creation of a plain
+ # +Polygon+, you should use <tt>validates :type, presence: true</tt>,
+ # 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.
diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb
index 0791811d94..2f1434b2bc 100644
--- a/activerecord/test/cases/dirty_test.rb
+++ b/activerecord/test/cases/dirty_test.rb
@@ -737,9 +737,7 @@ class DirtyTest < ActiveRecord::TestCase
end
test "virtual attributes are not written with partial_writes off" do
- original_partial_writes = ActiveRecord::Base.partial_writes
- begin
- ActiveRecord::Base.partial_writes = false
+ with_partial_writes(ActiveRecord::Base, false) do
klass = Class.new(ActiveRecord::Base) do
self.table_name = "people"
attribute :non_persisted_attribute, :string
@@ -753,8 +751,6 @@ class DirtyTest < ActiveRecord::TestCase
record.non_persisted_attribute_will_change!
assert record.save
- ensure
- ActiveRecord::Base.partial_writes = original_partial_writes
end
end