mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Merge pull request #17169 from kuldeepaggarwal/fix-STI-default-type
STI cast new instances to `default type` on initialize.
This commit is contained in:
commit
3da890f891
3 changed files with 47 additions and 9 deletions
|
@ -1,3 +1,16 @@
|
|||
* Respect the column default values for `inheritance_column` when
|
||||
instantiating records through the base class.
|
||||
|
||||
Fixes #17121.
|
||||
|
||||
Example:
|
||||
|
||||
# The schema of BaseModel has `t.string :type, default: 'SubType'`
|
||||
subtype = BaseModel.new
|
||||
assert_equals SubType, subtype.class
|
||||
|
||||
*Kuldeep Aggarwal*
|
||||
|
||||
* Fix `rake db:structure:dump` on Postgres when multiple schemas are used.
|
||||
|
||||
Fixes #22346.
|
||||
|
|
|
@ -51,8 +51,8 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
attrs = args.first
|
||||
if subclass_from_attributes?(attrs)
|
||||
subclass = subclass_from_attributes(attrs)
|
||||
if attribute_names.include?(inheritance_column)
|
||||
subclass = subclass_from_attributes(attrs) || subclass_from_defaults
|
||||
end
|
||||
|
||||
if subclass && subclass != self
|
||||
|
@ -197,16 +197,20 @@ module ActiveRecord
|
|||
# is not self or a valid subclass, raises ActiveRecord::SubclassNotFound
|
||||
# If this is a StrongParameters hash, and access to inheritance_column is not permitted,
|
||||
# this will ignore the inheritance column and return nil
|
||||
def subclass_from_attributes?(attrs)
|
||||
attribute_names.include?(inheritance_column) && (attrs.is_a?(Hash) || attrs.respond_to?(:permitted?))
|
||||
end
|
||||
|
||||
def subclass_from_attributes(attrs)
|
||||
attrs = attrs.to_h if attrs.respond_to?(:permitted?)
|
||||
subclass_name = attrs.with_indifferent_access[inheritance_column]
|
||||
if attrs.is_a?(Hash)
|
||||
subclass_name = attrs.with_indifferent_access[inheritance_column]
|
||||
|
||||
if subclass_name.present?
|
||||
find_sti_class(subclass_name)
|
||||
if subclass_name.present?
|
||||
find_sti_class(subclass_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def subclass_from_defaults
|
||||
if default = columns_hash[inheritance_column].default
|
||||
find_sti_class(default)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -478,4 +478,25 @@ class InheritanceComputeTypeTest < ActiveRecord::TestCase
|
|||
product = Shop::Product.new(:type => phone)
|
||||
assert product.save
|
||||
end
|
||||
|
||||
def test_inheritance_new_with_subclass_as_default
|
||||
original_type = Company.columns_hash["type"].default
|
||||
ActiveRecord::Base.connection.change_column_default :companies, :type, 'Firm'
|
||||
Company.reset_column_information
|
||||
|
||||
firm = Company.new # without arguments
|
||||
assert_equal 'Firm', firm.type
|
||||
assert_instance_of Firm, firm
|
||||
|
||||
firm = Company.new(firm_name: 'Shri Hans Plastic') # with arguments
|
||||
assert_equal 'Firm', firm.type
|
||||
assert_instance_of Firm, firm
|
||||
|
||||
firm = Company.new(type: 'Client') # overwrite the default type
|
||||
assert_equal 'Client', firm.type
|
||||
assert_instance_of Client, firm
|
||||
ensure
|
||||
ActiveRecord::Base.connection.change_column_default :companies, :type, original_type
|
||||
Company.reset_column_information
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue