Skip to content

Commit 79f34b9

Browse files
authored
Merge pull request rails#52892 from Shopify/assign_ids_first
Assign id attributes first in Active Record attribute assignment
2 parents 845ac2b + 210bc5b commit 79f34b9

File tree

2 files changed

+20
-9
lines changed

2 files changed

+20
-9
lines changed

activerecord/lib/active_record/attribute_assignment.rb

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,30 @@ module ActiveRecord
44
module AttributeAssignment
55
private
66
def _assign_attributes(attributes)
7-
multi_parameter_attributes = nested_parameter_attributes = nil
7+
foreign_keys = foreign_key_column_names
8+
foreign_key_attributes = nil
9+
normal_attributes = {}
10+
multi_parameter_attributes = nil
811

912
attributes.each do |k, v|
1013
key = k.to_s
1114

12-
if key.include?("(")
15+
if key.in?(foreign_keys)
16+
(foreign_key_attributes ||= {})[key] = v
17+
elsif key.include?("(")
1318
(multi_parameter_attributes ||= {})[key] = v
14-
elsif v.is_a?(Hash)
15-
(nested_parameter_attributes ||= {})[key] = v
1619
else
17-
_assign_attribute(key, v)
20+
normal_attributes[key] = v
1821
end
1922
end
2023

21-
assign_nested_parameter_attributes(nested_parameter_attributes) if nested_parameter_attributes
24+
foreign_key_attributes.each { |key, value| _assign_attribute(key, value) } if foreign_key_attributes
25+
normal_attributes.each { |key, value| _assign_attribute(key, value) }
2226
assign_multiparameter_attributes(multi_parameter_attributes) if multi_parameter_attributes
2327
end
2428

25-
# Assign any deferred nested attributes after the base attributes have been set.
26-
def assign_nested_parameter_attributes(pairs)
27-
pairs.each { |k, v| _assign_attribute(k, v) }
29+
def foreign_key_column_names
30+
self.class._reflections.values.grep(Reflection::BelongsToReflection).map(&:foreign_key)
2831
end
2932

3033
# Instantiates objects for all attribute classes that needs more than one constructor parameter. This is done

activerecord/test/cases/store_test.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,14 @@ class StoreTest < ActiveRecord::TestCase
220220
assert_equal "blue", user.color[:jenny]
221221
end
222222

223+
test "update store and accessor" do
224+
user = Admin::User.find_by_name("Jamis")
225+
user.update(settings: { homepage: "not rails" }, homepage: "rails")
226+
227+
assert_equal "rails", user.settings[:homepage]
228+
assert_equal "rails", user.homepage
229+
end
230+
223231
def test_convert_store_attributes_from_Hash_to_HashWithIndifferentAccess_saving_the_data_and_access_attributes_indifferently
224232
user = Admin::User.find_by_name("Jamis")
225233
assert_equal "symbol", user.settings[:symbol]

0 commit comments

Comments
 (0)