diff --git a/core/app/models/concerns/spree/preferences/persistable.rb b/core/app/models/concerns/spree/preferences/persistable.rb index a994a93e9b..b1508c62be 100644 --- a/core/app/models/concerns/spree/preferences/persistable.rb +++ b/core/app/models/concerns/spree/preferences/persistable.rb @@ -20,9 +20,10 @@ module Persistable private def initialize_preference_defaults - if has_attribute?(:preferences) - self.preferences = default_preferences.merge(preferences) - end + return unless has_attribute?(:preferences) + + merged = default_preferences.merge(preferences) + self.preferences = merged unless merged == preferences end end end diff --git a/core/spec/models/spree/preferences/preferable_spec.rb b/core/spec/models/spree/preferences/preferable_spec.rb index 6a283b36d6..16d4641736 100644 --- a/core/spec/models/spree/preferences/preferable_spec.rb +++ b/core/spec/models/spree/preferences/preferable_spec.rb @@ -387,6 +387,17 @@ class ComplexPreferableClass end end + it "does not re-serialize unchanged preferences when read after load" do + loaded = PrefTest.find(@pt.id) + + # NOTE: assigning preferences in after_initialize (even an identical value) flips + # the attribute to "from user" state, so every later read re-dumps YAML. Skipping + # the redundant assignment keeps reads on the cheaper "from database" path. + expect(Psych).not_to receive(:safe_dump) + + loaded.preferences + end + it "clear preferences when record is deleted" do @pt.save! @pt.preferred_pref_test_pref = "lmn"