mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Don't try to get the subclass if the inheritance column doesn't exist
The `subclass_from_attrs` method is called even if the column specified by the `inheritance_column` setting doesn't exist. This prevents setting associations via the attributes hash if the association name clashes with the value of the setting, typically `:type`. This worked previously in Rails 3.2.
This commit is contained in:
parent
b242b2dbe7
commit
e8d1d84837
5 changed files with 42 additions and 8 deletions
|
@ -1,3 +1,12 @@
|
|||
* Don't try to get the subclass if the inheritance column doesn't exist
|
||||
|
||||
The `subclass_from_attrs` method is called even if the column specified by
|
||||
the `inheritance_column` setting doesn't exist. This prevents setting associations
|
||||
via the attributes hash if the association name clashes with the value of the setting,
|
||||
typically `:type`. This worked previously in Rails 3.2.
|
||||
|
||||
*Ujjwal Thaakar*
|
||||
|
||||
* Enum mappings are now exposed via class methods instead of constants.
|
||||
|
||||
Example:
|
||||
|
|
|
@ -18,13 +18,17 @@ module ActiveRecord
|
|||
if abstract_class? || self == Base
|
||||
raise NotImplementedError, "#{self} is an abstract class and cannot be instantiated."
|
||||
end
|
||||
if (attrs = args.first).is_a?(Hash)
|
||||
if subclass = subclass_from_attrs(attrs)
|
||||
return subclass.new(*args, &block)
|
||||
end
|
||||
|
||||
attrs = args.first
|
||||
if subclass_from_attributes?(attrs)
|
||||
subclass = subclass_from_attributes(attrs)
|
||||
end
|
||||
|
||||
if subclass
|
||||
subclass.new(*args, &block)
|
||||
else
|
||||
super
|
||||
end
|
||||
# Delegate to the original .new
|
||||
super
|
||||
end
|
||||
|
||||
# Returns +true+ if this does not need STI type condition. Returns
|
||||
|
@ -172,7 +176,11 @@ 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_attrs(attrs)
|
||||
def subclass_from_attributes?(attrs)
|
||||
columns_hash.include?(inheritance_column) && attrs.is_a?(Hash)
|
||||
end
|
||||
|
||||
def subclass_from_attributes(attrs)
|
||||
subclass_name = attrs.with_indifferent_access[inheritance_column]
|
||||
|
||||
if subclass_name.present? && subclass_name != self.name
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
require "cases/helper"
|
||||
require 'cases/helper'
|
||||
require 'models/company'
|
||||
require 'models/person'
|
||||
require 'models/post'
|
||||
require 'models/project'
|
||||
require 'models/subscriber'
|
||||
require 'models/vegetables'
|
||||
require 'models/shop'
|
||||
|
||||
class InheritanceTest < ActiveRecord::TestCase
|
||||
fixtures :companies, :projects, :subscribers, :accounts, :vegetables
|
||||
|
@ -367,4 +368,10 @@ class InheritanceComputeTypeTest < ActiveRecord::TestCase
|
|||
ensure
|
||||
ActiveRecord::Base.store_full_sti_class = true
|
||||
end
|
||||
|
||||
def test_sti_type_from_attributes_disabled_in_non_sti_class
|
||||
phone = Shop::Product::Type.new(name: 'Phone')
|
||||
product = Shop::Product.new(:type => phone)
|
||||
assert product.save
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,6 +5,11 @@ module Shop
|
|||
|
||||
class Product < ActiveRecord::Base
|
||||
has_many :variants, :dependent => :delete_all
|
||||
belongs_to :type
|
||||
|
||||
class Type < ActiveRecord::Base
|
||||
has_many :products
|
||||
end
|
||||
end
|
||||
|
||||
class Variant < ActiveRecord::Base
|
||||
|
|
|
@ -557,9 +557,14 @@ ActiveRecord::Schema.define do
|
|||
|
||||
create_table :products, force: true do |t|
|
||||
t.references :collection
|
||||
t.references :type
|
||||
t.string :name
|
||||
end
|
||||
|
||||
create_table :product_types, force: true do |t|
|
||||
t.string :name
|
||||
end
|
||||
|
||||
create_table :projects, force: true do |t|
|
||||
t.string :name
|
||||
t.string :type
|
||||
|
|
Loading…
Reference in a new issue