Fix table_name in ActiveRecord with more than one abstract ancestors

When subclassing abstract_class table_name should be always computed
based on class name, no matter if superclass is subclassing base
or another abstract_class. So:

class FirstAbstract < ActiveRecord::Base
  self.abstract_class = true
end
class SecondAbstract < FirstAbstract
  self.abstract_class = true
end

class Post < SecondAbstract
  self.table_name #=> 'posts' (not 'second_abstracts')
end
This commit is contained in:
Piotr Sarnacki
2012-01-12 20:32:11 +01:00
parent ac153fe485
commit 0d1df723c7
2 changed files with 18 additions and 3 deletions

View File

@@ -139,10 +139,14 @@ module ActiveRecord
# Computes the table name, (re)sets it internally, and returns it.
def reset_table_name #:nodoc:
if superclass.abstract_class?
if abstract_class?
self.table_name = if superclass == Base || superclass.abstract_class?
nil
else
superclass.table_name
end
elsif superclass.abstract_class?
self.table_name = superclass.table_name || compute_table_name
elsif abstract_class?
self.table_name = superclass == Base ? nil : superclass.table_name
else
self.table_name = compute_table_name
end

View File

@@ -27,6 +27,13 @@ require 'rexml/document'
require 'active_support/core_ext/exception'
require 'bcrypt'
class FirstAbstractClass < ActiveRecord::Base
self.abstract_class = true
end
class SecondAbstractClass < FirstAbstractClass
self.abstract_class = true
end
class Photo < SecondAbstractClass; end
class Category < ActiveRecord::Base; end
class Categorization < ActiveRecord::Base; end
class Smarts < ActiveRecord::Base; end
@@ -2088,4 +2095,8 @@ class BasicsTest < ActiveRecord::TestCase
Bird.stubs(:scoped).returns(mock(:uniq => scope))
assert_equal scope, Bird.uniq
end
def test_table_name_with_2_abstract_subclasses
assert_equal "photos", Photo.table_name
end
end