diff --git a/CHANGELOG.md b/CHANGELOG.md index 56f20cf2f..18dda64eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ Note: For changes to the API, see https://shopify.dev/changelog?filter=api ## Unreleased +- Preserve in-place changes to nested REST attributes when saving resources. ## 16.3.0 (2026-08-04) - [#1443](https://github.com/Shopify/shopify-api-ruby/pull/1443) Add `ShopifyAPI::Utils::ShopValidator` with `sanitize_shop_domain` and `sanitize!`. diff --git a/lib/shopify_api/rest/base.rb b/lib/shopify_api/rest/base.rb index 3cc4ebd18..c69961039 100644 --- a/lib/shopify_api/rest/base.rb +++ b/lib/shopify_api/rest/base.rb @@ -3,6 +3,7 @@ require "active_support/inflector" require "active_support/core_ext/hash/indifferent_access" +require "active_support/core_ext/object/deep_dup" module ShopifyAPI module Rest @@ -301,6 +302,7 @@ def create_instance(data:, session:, instance: nil) end end + instance.original_state = instance.original_state.deep_dup instance end end diff --git a/test/clients/base_rest_resource_test.rb b/test/clients/base_rest_resource_test.rb index 78a2e19c8..5a72c77e0 100644 --- a/test/clients/base_rest_resource_test.rb +++ b/test/clients/base_rest_resource_test.rb @@ -315,6 +315,28 @@ def test_saves_removing_children assert_requested(stubbed_request) end + def test_saves_in_place_mutations_to_nested_attributes + resource = TestHelpers::FakeResource.create_instance( + session: @session, + data: { + "id" => 1, + "details" => { "address" => { "first_name" => "John" }, "tags" => ["original"] }, + }, + ) + stubbed_request = stub_request(:put, "#{@prefix}/fake_resources/1.json") + .with(body: hash_including( + "fake_resource" => hash_including( + "details" => { "address" => { "first_name" => "Jane" } }, + ), + )) + .to_return(status: 200) + + resource.details["address"]["first_name"] = "Jane" + resource.save + + assert_requested(stubbed_request) + end + def test_loads_unknown_attribute_with_special_character body = { fake_resource: { id: 1, attribute: "attribute", "unknown?": "some-value" } }.to_json