Mass assignment with inheritance column #9

Merged
merged 1 commit into from Jan 16, 2013
Jump to file or symbol
Failed to load files and symbols.
+45 −0
Split
@@ -8,6 +8,7 @@
require "active_record/mass_assignment_security/relation"
require "active_record/mass_assignment_security/validations"
require "active_record/mass_assignment_security/associations"
+require "active_record/mass_assignment_security/inheritance"
class ActiveRecord::Base
include ActiveRecord::MassAssignmentSecurity::Core
@@ -16,6 +17,7 @@ class ActiveRecord::Base
include ActiveRecord::MassAssignmentSecurity::Relation
include ActiveRecord::MassAssignmentSecurity::Validations
include ActiveRecord::MassAssignmentSecurity::NestedAttributes
+ include ActiveRecord::MassAssignmentSecurity::Inheritance
end
ActiveRecord::SchemaMigration.attr_accessible(:version)
@@ -0,0 +1,18 @@
+module ActiveRecord
+ module MassAssignmentSecurity
+ module Inheritance
+ extend ActiveSupport::Concern
+
+ module ClassMethods
+ private
+ # Detect the subclass from the inheritance column of attrs. If the inheritance column value
+ # 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)
+ active_authorizer[:default].deny?(inheritance_column) ? nil : super
+ end
+ end
+ end
+ end
+end
@@ -254,6 +254,24 @@ def test_protection_against_class_attribute_writers
assert !Task.new.respond_to?("#{method}=")
end
end
+
+ def test_new_with_protected_inheritance_column
+ firm = Company.new(type: "Firm")
+ assert_equal firm.class, Company
+ end
+
+ def test_new_with_accessible_inheritance_column
+ corporation = Corporation.new(type: "SpecialCorporation")
+ assert_equal corporation.class, SpecialCorporation
+ end
+
+ def test_new_with_invalid_inheritance_column_class
+ assert_raise(ActiveRecord::SubclassNotFound) { Corporation.new(type: "InvalidCorporation") }
+ end
+
+ def test_new_with_unrelated_inheritance_column_class
+ assert_raise(ActiveRecord::SubclassNotFound) { Corporation.new(type: "Person") }
+ end
end
View
@@ -96,3 +96,10 @@ def log_after_remove(record)
log << "after_remove#{record.id}"
end
end
+
+class Corporation < Company
+ attr_accessible :type, :name, :description
+end
+
+class SpecialCorporation < Corporation
+end