aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activerecord/CHANGELOG.md5
-rw-r--r--activerecord/lib/active_record/inheritance.rb14
-rw-r--r--activerecord/test/cases/inheritance_test.rb7
-rw-r--r--activerecord/test/models/company.rb3
4 files changed, 23 insertions, 6 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 4c67aac0d1..3663a6faa4 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,8 @@
+* Allow single table inheritance instantiation to work when storing
+ demodulized class names.
+
+ *Alex Robbin*
+
* Correctly pass MySQL options when using structure_dump or structure_load
Specifically, it fixes an issue when using SSL authentication.
diff --git a/activerecord/lib/active_record/inheritance.rb b/activerecord/lib/active_record/inheritance.rb
index 24098f72dc..a7801963e8 100644
--- a/activerecord/lib/active_record/inheritance.rb
+++ b/activerecord/lib/active_record/inheritance.rb
@@ -198,14 +198,16 @@ module ActiveRecord
def subclass_from_attributes(attrs)
subclass_name = attrs.with_indifferent_access[inheritance_column]
- if subclass_name.present? && subclass_name != self.name
- subclass = subclass_name.safe_constantize
+ if subclass_name.present?
+ subclass = find_sti_class(subclass_name)
- unless descendants.include?(subclass)
- raise ActiveRecord::SubclassNotFound.new("Invalid single-table inheritance type: #{subclass_name} is not a subclass of #{name}")
- end
+ if subclass.name != self.name
+ unless descendants.include?(subclass)
+ raise ActiveRecord::SubclassNotFound.new("Invalid single-table inheritance type: #{subclass_name} is not a subclass of #{name}")
+ end
- subclass
+ subclass
+ end
end
end
end
diff --git a/activerecord/test/cases/inheritance_test.rb b/activerecord/test/cases/inheritance_test.rb
index 278fa63e04..0286c85939 100644
--- a/activerecord/test/cases/inheritance_test.rb
+++ b/activerecord/test/cases/inheritance_test.rb
@@ -217,6 +217,13 @@ class InheritanceTest < ActiveRecord::TestCase
assert_nothing_raised { Client.new(type: 'VerySpecialClient') }
end
+ def test_new_without_storing_full_sti_class
+ without_store_full_sti_class do
+ item = Company.new(type: 'SpecialCo')
+ assert_instance_of Company::SpecialCo, item
+ end
+ end
+
def test_new_with_autoload_paths
path = File.expand_path('../../models/autoloadable', __FILE__)
ActiveSupport::Dependencies.autoload_paths << path
diff --git a/activerecord/test/models/company.rb b/activerecord/test/models/company.rb
index 6961f8fd6f..67936e8e5d 100644
--- a/activerecord/test/models/company.rb
+++ b/activerecord/test/models/company.rb
@@ -26,6 +26,9 @@ class Company < AbstractCompany
def private_method
"I am Jack's innermost fears and aspirations"
end
+
+ class SpecialCo < Company
+ end
end
module Namespaced