From c2e61aa61540802e5a5d9b54ff04b803d770eff6 Mon Sep 17 00:00:00 2001 From: Andrew White Date: Sun, 10 Jun 2012 16:23:34 +0100 Subject: Ensure that mass assignment options are preserved There are two possible scenarios where the @mass_assignment_options instance variable can become corrupted: 1. If the assign_attributes doesn't complete correctly, then subsequent calls to a nested attribute assignment method will use whatever options were passed to the previous assign_attributes call. 2. With nested assign_attributes calls, the inner call will overwrite the current options. This will only affect nested attributes as the attribute hash is sanitized before any methods are called. To fix this we save the current options in a local variable and then restore these options in an ensure block. --- .../lib/active_record/attribute_assignment.rb | 4 +++- activerecord/lib/active_record/core.rb | 19 ++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record/attribute_assignment.rb b/activerecord/lib/active_record/attribute_assignment.rb index bf9fe70b31..e0bf80142a 100644 --- a/activerecord/lib/active_record/attribute_assignment.rb +++ b/activerecord/lib/active_record/attribute_assignment.rb @@ -69,6 +69,7 @@ module ActiveRecord attributes = new_attributes.stringify_keys multi_parameter_attributes = [] nested_parameter_attributes = [] + previous_options = @mass_assignment_options @mass_assignment_options = options unless options[:without_protection] @@ -94,8 +95,9 @@ module ActiveRecord send("#{k}=", v) end - @mass_assignment_options = nil assign_multiparameter_attributes(multi_parameter_attributes) + ensure + @mass_assignment_options = previous_options end protected diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index 1fa6c701bb..dbad561ca2 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -380,15 +380,16 @@ module ActiveRecord @attributes[pk] = nil unless @attributes.key?(pk) - @aggregation_cache = {} - @association_cache = {} - @attributes_cache = {} - @previously_changed = {} - @changed_attributes = {} - @readonly = false - @destroyed = false - @marked_for_destruction = false - @new_record = true + @aggregation_cache = {} + @association_cache = {} + @attributes_cache = {} + @previously_changed = {} + @changed_attributes = {} + @readonly = false + @destroyed = false + @marked_for_destruction = false + @new_record = true + @mass_assignment_options = nil end end end -- cgit v1.2.3