From e71909ed713ecaadb42bb8c23f24fd47ff2cbc2a Mon Sep 17 00:00:00 2001 From: Nicholas Jakobsen Date: Wed, 28 Oct 2026 03:29:01 -0700 Subject: [PATCH] fix: Serialize JSON facets with `JSON.generate`, which ActiveSupport 6.1 doesn't break under json 3 Root cause: `Query::AbstractJsonFieldFacet#to_params` and `Query::FieldStats#to_params` serialized the facet with `to_json`. ActiveSupport overrides `Hash#to_json`, and ActiveSupport 6.1's encoder passes `quirks_mode` to `JSON.generate`, which json 3 no longer accepts, so any JSON facet, including `child_facet`, raised `ArgumentError: unknown keyword: quirks_mode` in an app on Rails 6.1 with json 3. Glint's Rails 6 CI hit it. Both now call `JSON.generate`, which doesn't depend on what an app's ActiveSupport does to `to_json`. Co-Authored-By: Claude Opus 5.5 --- sunspot/lib/sunspot/query/abstract_json_field_facet.rb | 4 ++-- sunspot/lib/sunspot/query/field_stats.rb | 2 +- sunspot/spec/api/nested_documents_spec.rb | 7 +++++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/sunspot/lib/sunspot/query/abstract_json_field_facet.rb b/sunspot/lib/sunspot/query/abstract_json_field_facet.rb index 8c6d8c2e4..8a22f1f69 100644 --- a/sunspot/lib/sunspot/query/abstract_json_field_facet.rb +++ b/sunspot/lib/sunspot/query/abstract_json_field_facet.rb @@ -1,4 +1,4 @@ -require 'json' # to_params serializes the facet with to_json +require 'json' module Sunspot module Query @@ -49,7 +49,7 @@ def get_params end def to_params - { 'json.facet' => self.get_params.to_json } + { 'json.facet' => JSON.generate(get_params) } end private diff --git a/sunspot/lib/sunspot/query/field_stats.rb b/sunspot/lib/sunspot/query/field_stats.rb index c7189522d..0f95e8870 100644 --- a/sunspot/lib/sunspot/query/field_stats.rb +++ b/sunspot/lib/sunspot/query/field_stats.rb @@ -17,7 +17,7 @@ def add_json_facet(json_facet) def to_params params = {} if !@json_facet.nil? - params['json.facet'] = recursive_add_stats(@json_facet.get_params).to_json + params['json.facet'] = JSON.generate(recursive_add_stats(@json_facet.get_params)) else params.merge!(:stats => true, :"stats.field" => [@field.indexed_name]) params[facet_key] = @facets.map(&:indexed_name) unless @facets.empty? diff --git a/sunspot/spec/api/nested_documents_spec.rb b/sunspot/spec/api/nested_documents_spec.rb index f3d5fd072..07acce93e 100644 --- a/sunspot/spec/api/nested_documents_spec.rb +++ b/sunspot/spec/api/nested_documents_spec.rb @@ -348,6 +348,13 @@ def json_facet }) end + it "serializes its params with JSON.generate, not Hash#to_json, which ActiveSupport 6.1 breaks under json 3" do + allow_any_instance_of(Hash).to receive(:to_json).and_raise(ArgumentError, 'unknown keyword: quirks_mode') + + session.search(Project) { child_facet(:milestones, :name) } + expect(json_facet.keys).to eq(['name']) + end + it 'is keyed by its :name' do session.search(Project) { child_facet(:milestones, :name, :name => :milestone_name) } expect(json_facet.keys).to eq(['milestone_name'])