aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorAlex Robbin <alex.robbin@meyouhealth.com>2015-03-26 13:26:19 -0400
committerAlex Robbin <alex.robbin@meyouhealth.com>2015-05-11 09:02:48 -0400
commitcbd66b430b6553e468bcdaa94af661a2d8b69d81 (patch)
treefbd365f821265d2d3eccaa5a3908814609543f29 /activerecord
parentdb0e649aba7135133154a35549219cffe968eaf6 (diff)
downloadrails-cbd66b430b6553e468bcdaa94af661a2d8b69d81.tar.gz
rails-cbd66b430b6553e468bcdaa94af661a2d8b69d81.tar.bz2
rails-cbd66b430b6553e468bcdaa94af661a2d8b69d81.zip
allow setting of a demodulized class name when using STI
If your STI class looks like this: ```ruby class Company < ActiveRecord::Base self.store_full_sti_class = false class GoodCo < Company end class BadCo < Company end end ``` The expectation (which is valid) is that the `type` in the database is saved as `GoodCo` or `BadCo`. However, another expectation should be that setting `type` to `GoodCo` would correctly instantiate the object as a `Company::GoodCo`. That second expectation is what this should fix.
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG.md4
-rw-r--r--activerecord/lib/active_record/inheritance.rb14
-rw-r--r--activerecord/test/cases/inheritance_test.rb8
-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 09045087d9..d02d8912a3 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,7 @@
+* Allow setting of a demodulized class name whenusing single table inheritance.
+
+ *Alex Robbin*
+
* Dump indexes in `create_table` instead of `add_index`.
If the adapter supports indexes in create table, generated SQL is
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..9199066072 100644
--- a/activerecord/test/cases/inheritance_test.rb
+++ b/activerecord/test/cases/inheritance_test.rb
@@ -217,6 +217,14 @@ 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
+ Company::SpecialCo # force autoloading
+ 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