aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG21
-rw-r--r--activerecord/lib/active_record/associations/association_proxy.rb2
-rw-r--r--activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb2
-rw-r--r--activerecord/lib/active_record/associations/has_many_association.rb2
-rw-r--r--activerecord/lib/active_record/associations/has_many_through_association.rb2
-rw-r--r--activerecord/lib/active_record/associations/has_one_association.rb2
-rwxr-xr-xactiverecord/lib/active_record/base.rb22
-rw-r--r--activerecord/lib/active_record/calculations.rb2
-rw-r--r--activerecord/test/associations_join_model_test.rb10
-rwxr-xr-xactiverecord/test/base_test.rb9
-rw-r--r--activerecord/test/fixtures/post.rb4
11 files changed, 62 insertions, 16 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index 0ef11609ee..577670d84f 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,5 +1,26 @@
*SVN*
+* Added Base.abstract_class? that marks which classes are not part of the Active Record hierarchy #3704 [Rick Olson]
+
+ class CachedModel < ActiveRecord::Base
+ self.abstract_class = true
+ end
+
+ class Post < CachedModel
+ end
+
+ CachedModel.abstract_class?
+ => true
+
+ Post.abstract_class?
+ => false
+
+ Post.base_class
+ => Post
+
+ Post.table_name
+ => 'posts'
+
* Allow :dependent options to be used with polymorphic joins. #3820 [Rick Olson]
class Foo < ActiveRecord::Base
diff --git a/activerecord/lib/active_record/associations/association_proxy.rb b/activerecord/lib/active_record/associations/association_proxy.rb
index a4fc85b15e..d340cc30e3 100644
--- a/activerecord/lib/active_record/associations/association_proxy.rb
+++ b/activerecord/lib/active_record/associations/association_proxy.rb
@@ -77,7 +77,7 @@ module ActiveRecord
def set_belongs_to_association_for(record)
if @reflection.options[:as]
record["#{@reflection.options[:as]}_id"] = @owner.id unless @owner.new_record?
- record["#{@reflection.options[:as]}_type"] = ActiveRecord::Base.send(:class_name_of_active_record_descendant, @owner.class).to_s
+ record["#{@reflection.options[:as]}_type"] = @owner.class.base_class.name.to_s
else
record[@reflection.primary_key_name] = @owner.id unless @owner.new_record?
end
diff --git a/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb b/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb
index 6c2b9b89fd..6d0704db74 100644
--- a/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb
+++ b/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb
@@ -9,7 +9,7 @@ module ActiveRecord
unless record.new_record?
@owner[@reflection.primary_key_name] = record.id
- @owner[@reflection.options[:foreign_type]] = ActiveRecord::Base.send(:class_name_of_active_record_descendant, record.class).to_s
+ @owner[@reflection.options[:foreign_type]] = record.class.base_class.name.to_s
end
@updated = true
diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb
index b861fde55d..8b471859c1 100644
--- a/activerecord/lib/active_record/associations/has_many_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_association.rb
@@ -168,7 +168,7 @@ module ActiveRecord
when @reflection.options[:as]
@finder_sql =
"#{@reflection.klass.table_name}.#{@reflection.options[:as]}_id = #{@owner.quoted_id} AND " +
- "#{@reflection.klass.table_name}.#{@reflection.options[:as]}_type = '#{ActiveRecord::Base.send(:class_name_of_active_record_descendant, @owner.class).to_s}'"
+ "#{@reflection.klass.table_name}.#{@reflection.options[:as]}_type = #{@owner.class.quote @owner.class.base_class.name.to_s}"
@finder_sql << " AND (#{interpolate_sql(@conditions)})" if @conditions
else
diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb
index 413f56857f..6db5eae0bc 100644
--- a/activerecord/lib/active_record/associations/has_many_through_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_through_association.rb
@@ -67,7 +67,7 @@ module ActiveRecord
conditions =
"#{@reflection.table_name}.#{@reflection.klass.primary_key} = #{through_reflection.table_name}.#{@reflection.klass.to_s.foreign_key} " +
"AND #{through_reflection.table_name}.#{through_reflection.options[:as]}_id = #{@owner.quoted_id} " +
- "AND #{through_reflection.table_name}.#{through_reflection.options[:as]}_type = '#{ActiveRecord::Base.send(:class_name_of_active_record_descendant, @owner.class).to_s}'"
+ "AND #{through_reflection.table_name}.#{through_reflection.options[:as]}_type = #{@owner.class.quote @owner.class.base_class.name.to_s}"
else
conditions =
"#{@reflection.klass.table_name}.#{@reflection.klass.primary_key} = #{through_reflection.table_name}.#{@reflection.klass.to_s.foreign_key} " +
diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb
index 65f584c6f9..e0d6f64b27 100644
--- a/activerecord/lib/active_record/associations/has_one_association.rb
+++ b/activerecord/lib/active_record/associations/has_one_association.rb
@@ -69,7 +69,7 @@ module ActiveRecord
when @reflection.options[:as]
@finder_sql =
"#{@reflection.klass.table_name}.#{@reflection.options[:as]}_id = #{@owner.quoted_id} AND " +
- "#{@reflection.klass.table_name}.#{@reflection.options[:as]}_type = '#{ActiveRecord::Base.send(:class_name_of_active_record_descendant, @owner.class).to_s}'"
+ "#{@reflection.klass.table_name}.#{@reflection.options[:as]}_type = #{@owner.class.quote @owner.class.base_class.name.to_s}"
else
@finder_sql = "#{@reflection.table_name}.#{@reflection.primary_key_name} = #{@owner.quoted_id}"
end
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 8c1f615a37..a4505733de 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -599,7 +599,7 @@ module ActiveRecord #:nodoc:
end
def reset_table_name
- name = "#{table_name_prefix}#{undecorated_table_name(class_name_of_active_record_descendant(self))}#{table_name_suffix}"
+ name = "#{table_name_prefix}#{undecorated_table_name(base_class.name)}#{table_name_suffix}"
set_table_name(name)
name
end
@@ -614,9 +614,9 @@ module ActiveRecord #:nodoc:
key = 'id'
case primary_key_prefix_type
when :table_name
- key = Inflector.foreign_key(class_name_of_active_record_descendant(self), false)
+ key = Inflector.foreign_key(base_class.name, false)
when :table_name_with_underscore
- key = Inflector.foreign_key(class_name_of_active_record_descendant(self))
+ key = Inflector.foreign_key(base_class.name)
end
set_primary_key(key)
key
@@ -936,7 +936,15 @@ module ActiveRecord #:nodoc:
class_of_active_record_descendant(self)
end
-
+ # Set this to true if this is an abstract class (see #abstract_class?).
+ attr_accessor :abstract_class
+
+ # Returns whether this class is a base AR class. If A is a base class and
+ # B descends from A, then B.base_class will return B.
+ def abstract_class?
+ abstract_class == true
+ end
+
private
# Finder methods must instantiate through this method to work with the single-table inheritance model
# that makes it possible to create objects of different types from the same table.
@@ -1016,7 +1024,7 @@ module ActiveRecord #:nodoc:
end
# Guesses the table name, but does not decorate it with prefix and suffix information.
- def undecorated_table_name(class_name = class_name_of_active_record_descendant(self))
+ def undecorated_table_name(class_name = base_class.name)
table_name = Inflector.underscore(Inflector.demodulize(class_name))
table_name = Inflector.pluralize(table_name) if pluralize_table_names
table_name
@@ -1172,7 +1180,7 @@ module ActiveRecord #:nodoc:
# Returns the class descending directly from ActiveRecord in the inheritance hierarchy.
def class_of_active_record_descendant(klass)
- if klass.superclass == Base
+ if klass.superclass == Base || klass.superclass.abstract_class?
klass
elsif klass.superclass.nil?
raise ActiveRecordError, "#{name} doesn't belong in a hierarchy descending from ActiveRecord"
@@ -1183,7 +1191,7 @@ module ActiveRecord #:nodoc:
# Returns the name of the class descending directly from ActiveRecord in the inheritance hierarchy.
def class_name_of_active_record_descendant(klass)
- class_of_active_record_descendant(klass).name
+ klass.base_class.name
end
# Accepts an array or string. The string is returned untouched, but the array has each value
diff --git a/activerecord/lib/active_record/calculations.rb b/activerecord/lib/active_record/calculations.rb
index 6c5ae3edca..af976f532f 100644
--- a/activerecord/lib/active_record/calculations.rb
+++ b/activerecord/lib/active_record/calculations.rb
@@ -172,7 +172,7 @@ module ActiveRecord
if association
key_ids = calculated_data.collect { |row| row[group_alias] }
- key_records = ActiveRecord::Base.send(:class_of_active_record_descendant, association.klass).find(key_ids)
+ key_records = association.klass.base_class.find(key_ids)
key_records = key_records.inject({}) { |hsh, r| hsh.merge(r.id => r) }
end
diff --git a/activerecord/test/associations_join_model_test.rb b/activerecord/test/associations_join_model_test.rb
index 2d74895664..58208ced65 100644
--- a/activerecord/test/associations_join_model_test.rb
+++ b/activerecord/test/associations_join_model_test.rb
@@ -38,7 +38,15 @@ class AssociationsJoinModelTest < Test::Unit::TestCase
def test_polymorphic_has_many_going_through_join_model
assert_equal tags(:general), posts(:welcome).tags.first
end
-
+
+ def test_polymorphic_has_many_create_model_with_inheritance_and_custom_base_class
+ post = SubStiPost.create :title => 'SubStiPost', :body => 'SubStiPost body'
+ assert_instance_of SubStiPost, post
+
+ tagging = tags(:misc).taggings.create(:taggable => post)
+ assert_equal "SubStiPost", tagging.taggable_type
+ end
+
def test_polymorphic_has_many_going_through_join_model_with_inheritance
assert_equal tags(:general), posts(:thinking).tags.first
end
diff --git a/activerecord/test/base_test.rb b/activerecord/test/base_test.rb
index d910215a0a..de08118240 100755
--- a/activerecord/test/base_test.rb
+++ b/activerecord/test/base_test.rb
@@ -21,6 +21,7 @@ class TestOracleDefault < ActiveRecord::Base; end
class LoosePerson < ActiveRecord::Base
attr_protected :credit_rating, :administrator
+ self.abstract_class = true
end
class LooseDescendant < LoosePerson
@@ -1148,8 +1149,12 @@ class BasicsTest < Test::Unit::TestCase
end
def test_base_class
- assert_equal LoosePerson, LoosePerson.base_class
- assert_equal LoosePerson, LooseDescendant.base_class
+ assert LoosePerson.abstract_class?
+ assert !LooseDescendant.abstract_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_assert_queries
diff --git a/activerecord/test/fixtures/post.rb b/activerecord/test/fixtures/post.rb
index e5b95aff32..a00fd80671 100644
--- a/activerecord/test/fixtures/post.rb
+++ b/activerecord/test/fixtures/post.rb
@@ -39,5 +39,9 @@ end
class SpecialPost < Post; end;
class StiPost < Post
+ self.abstract_class = true
has_one :special_comment, :class_name => "SpecialComment"
end
+
+class SubStiPost < StiPost
+end