From d0aebd5357a5fcbb2f55963e4191e26458ad6d72 Mon Sep 17 00:00:00 2001 From: beerlington Date: Thu, 26 Jul 2012 13:46:49 -0400 Subject: Refactor ActiveRecord::Inheritance.base_class logic Moved logic from class_of_active_record_descendant(class) to the base_class method. This method was confusing because it required an argument, but that argument was 'self'. Moved base_class tests to inheritance_test.rb and added some test coverage for some untested cases. --- activerecord/lib/active_record/inheritance.rb | 33 ++++++++++++--------------- activerecord/test/cases/base_test.rb | 12 ---------- activerecord/test/cases/inheritance_test.rb | 30 ++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 30 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/inheritance.rb b/activerecord/lib/active_record/inheritance.rb index 770083ac13..4a24024105 100644 --- a/activerecord/lib/active_record/inheritance.rb +++ b/activerecord/lib/active_record/inheritance.rb @@ -41,14 +41,26 @@ module ActiveRecord @symbolized_sti_name ||= sti_name.present? ? sti_name.to_sym : symbolized_base_class end - # Returns the base AR subclass that this class descends from. If A - # extends AR::Base, A.base_class will return A. If B descends from A + # Returns the class descending directly from ActiveRecord::Base (or + # that includes ActiveRecord::Model), or an abstract class, if any, in + # the inheritance hierarchy. + # + # If A extends AR::Base, A.base_class will return A. If B descends from A # through some arbitrarily deep hierarchy, B.base_class will return A. # # If B < A and C < B and if A is an abstract_class then both B.base_class # and C.base_class would return B as the answer since A is an abstract_class. def base_class - class_of_active_record_descendant(self) + unless self < Model::Tag + raise ActiveRecordError, "#{name} doesn't belong in a hierarchy descending from ActiveRecord" + end + + sup = active_record_super + if sup.in?([Base, Model]) || sup.abstract_class? + self + else + sup.base_class + end end # Set this to true if this is an abstract class (see abstract_class?). @@ -96,21 +108,6 @@ module ActiveRecord protected - # Returns the class descending directly from ActiveRecord::Base or an - # abstract class, if any, in the inheritance hierarchy. - def class_of_active_record_descendant(klass) - unless klass < Model::Tag - raise ActiveRecordError, "#{name} doesn't belong in a hierarchy descending from ActiveRecord" - end - - sup = klass.active_record_super - if [Base, Model].include?(klass) || [Base, Model].include?(sup) || sup.abstract_class? - klass - else - class_of_active_record_descendant(sup) - end - end - # Returns the class type of the record using the current module as a prefix. So descendants of # MyApp::Business::Account would appear as MyApp::Business::AccountSubclass. def compute_type(type_name) diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index a117568c85..8a30ee5fc8 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -1619,18 +1619,6 @@ class BasicsTest < ActiveRecord::TestCase assert_nil AbstractCompany.table_name end - def test_base_class - assert_equal LoosePerson, LoosePerson.base_class - assert_equal LooseDescendant, LooseDescendant.base_class - assert_equal TightPerson, TightPerson.base_class - assert_equal TightPerson, TightDescendant.base_class - - assert_equal Post, Post.base_class - assert_equal Post, SpecialPost.base_class - assert_equal Post, StiPost.base_class - assert_equal SubStiPost, SubStiPost.base_class - end - def test_descends_from_active_record assert !ActiveRecord::Base.descends_from_active_record? diff --git a/activerecord/test/cases/inheritance_test.rb b/activerecord/test/cases/inheritance_test.rb index 06de51f5cd..78fd10322a 100644 --- a/activerecord/test/cases/inheritance_test.rb +++ b/activerecord/test/cases/inheritance_test.rb @@ -1,7 +1,10 @@ require "cases/helper" require 'models/company' +require 'models/person' +require 'models/post' require 'models/project' require 'models/subscriber' +require 'models/teapot' class InheritanceTest < ActiveRecord::TestCase fixtures :companies, :projects, :subscribers, :accounts @@ -70,6 +73,33 @@ class InheritanceTest < ActiveRecord::TestCase assert !Class.new(Company).descends_from_active_record?, 'Company subclass should not descend from ActiveRecord::Base' end + def test_inheritance_base_class + assert_equal Post, Post.base_class + assert_equal Post, SpecialPost.base_class + assert_equal Post, StiPost.base_class + assert_equal SubStiPost, SubStiPost.base_class + end + + def test_active_record_model_included_base_class + assert_equal Teapot, Teapot.base_class + end + + def test_abstract_inheritance_base_class + assert_equal LoosePerson, LoosePerson.base_class + assert_equal LooseDescendant, LooseDescendant.base_class + assert_equal TightPerson, TightPerson.base_class + assert_equal TightPerson, TightDescendant.base_class + end + + def test_base_class_activerecord_error + klass = Class.new { + extend ActiveRecord::Configuration + include ActiveRecord::Inheritance + } + + assert_raise(ActiveRecord::ActiveRecordError) { klass.base_class } + end + def test_a_bad_type_column #SQLServer need to turn Identity Insert On before manually inserting into the Identity column if current_adapter?(:SybaseAdapter) -- cgit v1.2.3