1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

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.
This commit is contained in:
Alex Robbin 2015-03-26 13:26:19 -04:00
parent db0e649aba
commit cbd66b430b
4 changed files with 23 additions and 6 deletions

View file

@ -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

View file

@ -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}")
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
end
subclass
end
end
end

View file

@ -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

View file

@ -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