Skip to content

Commit 7abd9b5

Browse files
committed
Precompute Inheritance.base_class
This saves checking the inehritance chain on each access.
1 parent 9904926 commit 7abd9b5

File tree

2 files changed

+25
-13
lines changed

2 files changed

+25
-13
lines changed

activerecord/lib/active_record/inheritance.rb

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ module Inheritance
4343
# Determines whether to store the full constant name including namespace when using STI.
4444
# This is true, by default.
4545
class_attribute :store_full_sti_class, instance_writer: false, default: true
46+
47+
set_base_class
4648
end
4749

4850
module ClassMethods
@@ -98,17 +100,7 @@ def finder_needs_type_condition? #:nodoc:
98100
#
99101
# If B < A and C < B and if A is an abstract_class then both B.base_class
100102
# and C.base_class would return B as the answer since A is an abstract_class.
101-
def base_class
102-
unless self < Base
103-
raise ActiveRecordError, "#{name} doesn't belong in a hierarchy descending from ActiveRecord"
104-
end
105-
106-
if superclass == Base || superclass.abstract_class?
107-
self
108-
else
109-
superclass.base_class
110-
end
111-
end
103+
attr_reader :base_class
112104

113105
# Returns whether the class is a base class.
114106
# See #base_class for more information.
@@ -218,6 +210,7 @@ def polymorphic_class_for(name)
218210
end
219211

220212
def inherited(subclass)
213+
subclass.set_base_class
221214
subclass.instance_variable_set(:@_type_candidates_cache, Concurrent::Map.new)
222215
super
223216
end
@@ -253,6 +246,24 @@ def compute_type(type_name)
253246
end
254247
end
255248

249+
def set_base_class # :nodoc:
250+
@base_class = begin
251+
if self == Base
252+
self
253+
else
254+
unless self < Base
255+
raise ActiveRecordError, "#{name} doesn't belong in a hierarchy descending from ActiveRecord"
256+
end
257+
258+
if superclass == Base || superclass.abstract_class?
259+
self
260+
else
261+
superclass.base_class
262+
end
263+
end
264+
end
265+
end
266+
256267
private
257268
# Called by +instantiate+ to decide which class to use for a new
258269
# record instance. For single-table inheritance, we check the record

activerecord/test/cases/inheritance_test.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,9 @@ def test_abstract_inheritance_base_class
190190
end
191191

192192
def test_base_class_activerecord_error
193-
klass = Class.new { include ActiveRecord::Inheritance }
194-
assert_raise(ActiveRecord::ActiveRecordError) { klass.base_class }
193+
assert_raise(ActiveRecord::ActiveRecordError) do
194+
Class.new { include ActiveRecord::Inheritance }
195+
end
195196
end
196197

197198
def test_a_bad_type_column

0 commit comments

Comments
 (0)