From e315fb94ec2f1c8a8d1cb5f14857e6984eb9a6b8 Mon Sep 17 00:00:00 2001 From: Chris Beer Date: Fri, 22 May 2026 14:39:42 -0700 Subject: [PATCH 1/5] Allow Blacklight::SearchService#search_results to take params as an argument. --- app/services/blacklight/search_service.rb | 15 +++++++++------ spec/services/blacklight/search_service_spec.rb | 8 ++++++++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/app/services/blacklight/search_service.rb b/app/services/blacklight/search_service.rb index 4c0a234de..2de04b656 100644 --- a/app/services/blacklight/search_service.rb +++ b/app/services/blacklight/search_service.rb @@ -29,13 +29,16 @@ def search_builder # SearchBuilder to be used. Block should return SearchBuilder to be used. # This is used in blacklight_range_limit # @return [Blacklight::Solr::Response] the solr response object - def search_results - builder = search_builder.with(search_state) - builder.page = search_state.page - builder.rows = search_state.per_page + def search_results(params: nil) + unless params + builder = search_builder.with(search_state) + builder.page = search_state.page + builder.rows = search_state.per_page + + builder = yield(builder) if block_given? + end - builder = yield(builder) if block_given? - response = repository.search(params: builder) + response = repository.search(params: params || builder) if response.grouped? && grouped_key_for_results response.group(grouped_key_for_results) diff --git a/spec/services/blacklight/search_service_spec.rb b/spec/services/blacklight/search_service_spec.rb index 1a6bf5c59..652d2a4e1 100644 --- a/spec/services/blacklight/search_service_spec.rb +++ b/spec/services/blacklight/search_service_spec.rb @@ -129,6 +129,14 @@ expect(solr_response.docs).to have(0).results end end + + describe 'when passing in the params' do + it 'returns the results' do + solr_response = service.search_results(params: { q: '', rows: 5 }) + + expect(solr_response.docs).to have(5).results + end + end end # Search Results # SPECS FOR SEARCH RESULTS FOR FACETS From 22eac798f2e6fe8ac6671fe322dee8dfae40f67b Mon Sep 17 00:00:00 2001 From: Chris Beer Date: Fri, 22 May 2026 14:50:30 -0700 Subject: [PATCH 2/5] Add Blacklight::Searchable#search_builder --- app/controllers/concerns/blacklight/searchable.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/controllers/concerns/blacklight/searchable.rb b/app/controllers/concerns/blacklight/searchable.rb index 2c0982149..9dc78e5b4 100644 --- a/app/controllers/concerns/blacklight/searchable.rb +++ b/app/controllers/concerns/blacklight/searchable.rb @@ -42,6 +42,11 @@ def retrieve_documents(ids) search_service.fetch(Array(ids)) end + # @return [Blacklight::SearchBuilder] + def search_builder + blacklight_config.search_builder_class.new(self, blacklight_config: blacklight_config).with(search_state) + end + # Override this method on the class that includes Blacklight::Searchable to provide more context to the search service if necessary. # For example, if your search builder needs to be aware of the current user, override this method to return a hash including the current user. # Then the search builder could use some property about the current user to construct a constraint on the search. From 1e67e18756b127913b355cb184b20ce8ecfb70b8 Mon Sep 17 00:00:00 2001 From: Chris Beer Date: Fri, 22 May 2026 15:33:11 -0700 Subject: [PATCH 3/5] Use search_builder to construct queries from the controller. --- app/controllers/concerns/blacklight/catalog.rb | 12 +++++++----- app/controllers/concerns/blacklight/searchable.rb | 6 +++--- app/services/blacklight/bookmarks_search_builder.rb | 2 +- app/services/blacklight/search_service.rb | 7 +++---- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/app/controllers/concerns/blacklight/catalog.rb b/app/controllers/concerns/blacklight/catalog.rb index dc380e9f8..184569d8b 100644 --- a/app/controllers/concerns/blacklight/catalog.rb +++ b/app/controllers/concerns/blacklight/catalog.rb @@ -80,11 +80,13 @@ def facet @facet = blacklight_config.facet_fields[params[:id]] raise ActionController::RoutingError, 'Not Found' unless @facet - @response = if params[:query_fragment].present? - search_service.facet_suggest_response(@facet.key, params[:query_fragment]) - else - search_service.facet_field_response(@facet.key) - end + builder = search_builder.with(search_state).facet(@facet.key) + if params[:query_fragment].present? + builder = builder.facet_suggestion_query(params[:query_fragment]) + end + + @response = retrieve_search_results(params: builder) + # @display_facet is a Blacklight::Solr::Response::Facets::FacetField @display_facet = @response.aggregations[@facet.field] diff --git a/app/controllers/concerns/blacklight/searchable.rb b/app/controllers/concerns/blacklight/searchable.rb index 9dc78e5b4..f6fd18677 100644 --- a/app/controllers/concerns/blacklight/searchable.rb +++ b/app/controllers/concerns/blacklight/searchable.rb @@ -26,8 +26,8 @@ def search_service # This method may be overridden to customize search behavior. # @return [Blacklight::Solr::Response] the solr response object - def retrieve_search_results - search_service.search_results + def retrieve_search_results(params: nil) + search_service.search_results(params: params || search_builder.with(search_state).rows(search_state.per_page).page(search_state.page)) end # This method may be overridden to customize search behavior. @@ -44,7 +44,7 @@ def retrieve_documents(ids) # @return [Blacklight::SearchBuilder] def search_builder - blacklight_config.search_builder_class.new(self, blacklight_config: blacklight_config).with(search_state) + blacklight_config.search_builder_class.new(self, blacklight_config: blacklight_config) end # Override this method on the class that includes Blacklight::Searchable to provide more context to the search service if necessary. diff --git a/app/services/blacklight/bookmarks_search_builder.rb b/app/services/blacklight/bookmarks_search_builder.rb index cff2ae905..a9edb2099 100644 --- a/app/services/blacklight/bookmarks_search_builder.rb +++ b/app/services/blacklight/bookmarks_search_builder.rb @@ -11,7 +11,7 @@ class BookmarksSearchBuilder < ::SearchBuilder # @return [void] def bookmarked(solr_parameters) solr_parameters[:fq] ||= [] - bookmarks = @scope.context.fetch(:bookmarks) + bookmarks = @scope.search_service_context.fetch(:bookmarks) return unless bookmarks document_ids = bookmarks.collect { |b| b.document_id.to_s } diff --git a/app/services/blacklight/search_service.rb b/app/services/blacklight/search_service.rb index 2de04b656..a427be329 100644 --- a/app/services/blacklight/search_service.rb +++ b/app/services/blacklight/search_service.rb @@ -31,10 +31,7 @@ def search_builder # @return [Blacklight::Solr::Response] the solr response object def search_results(params: nil) unless params - builder = search_builder.with(search_state) - builder.page = search_state.page - builder.rows = search_state.per_page - + builder = search_builder.with(search_state).page(search_state.page).rows(search_state.per_page) builder = yield(builder) if block_given? end @@ -63,12 +60,14 @@ def fetch(id = nil, extra_controller_params = {}) ## # Get the solr response when retrieving only a single facet field + # @deprecated # @return [Blacklight::Solr::Response] the solr response def facet_field_response(facet_field, extra_controller_params = {}) query = search_builder.with(search_state).facet(facet_field) repository.search(params: query.merge(extra_controller_params)) end + # @deprecated def facet_suggest_response(facet_field, facet_suggestion_query, extra_controller_params = {}) query = search_builder.with(search_state).facet(facet_field).facet_suggestion_query(facet_suggestion_query) repository.search(params: query.merge(extra_controller_params)) From 2408af121268ed1f1b860c40cfd0aafe69f1ce56 Mon Sep 17 00:00:00 2001 From: Chris Beer Date: Mon, 25 May 2026 09:22:41 -0700 Subject: [PATCH 4/5] Guard against SearchBuilder implementations that don't support the new blacklight_config kwarg --- app/controllers/concerns/blacklight/searchable.rb | 9 ++++++++- lib/blacklight/search_builder.rb | 8 ++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/app/controllers/concerns/blacklight/searchable.rb b/app/controllers/concerns/blacklight/searchable.rb index f6fd18677..9b60dd747 100644 --- a/app/controllers/concerns/blacklight/searchable.rb +++ b/app/controllers/concerns/blacklight/searchable.rb @@ -44,7 +44,14 @@ def retrieve_documents(ids) # @return [Blacklight::SearchBuilder] def search_builder - blacklight_config.search_builder_class.new(self, blacklight_config: blacklight_config) + klass = blacklight_config.search_builder_class + + if klass.initialize_supports_blacklight_config_parameter? + klass.new(self, blacklight_config: blacklight_config) + else + # deprecated behavior for implementations that don't support the new initializer signature. + klass.new(self) + end end # Override this method on the class that includes Blacklight::Searchable to provide more context to the search service if necessary. diff --git a/lib/blacklight/search_builder.rb b/lib/blacklight/search_builder.rb index 3f49cd625..135b0083c 100644 --- a/lib/blacklight/search_builder.rb +++ b/lib/blacklight/search_builder.rb @@ -33,6 +33,14 @@ def initialize(*options, blacklight_config: nil) @reverse_merged_params = {} end + def self.initialize_supports_blacklight_config_parameter? + return @initialize_supports_blacklight_config_parameter if defined?(@initialize_supports_blacklight_config_parameter) + + @initialize_supports_blacklight_config_parameter = instance_method(:initialize).parameters.any? { |_type, name| name == :blacklight_config } + + Blacklight.deprecation.warn "#{self} initializer should accept a blacklight_config keyword argument in its initializer. This will be required in Blacklight 10." + end + def search_state @search_state ||= begin search_state_class = @scope.try(:search_state_class) || Blacklight::SearchState From 4a5863b818fc0034d2f658bcf521df7ec534094b Mon Sep 17 00:00:00 2001 From: Chris Beer Date: Wed, 27 May 2026 09:06:00 -0700 Subject: [PATCH 5/5] Make search_state an optional parameter to Blacklight::SearchService --- app/services/blacklight/search_service.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/services/blacklight/search_service.rb b/app/services/blacklight/search_service.rb index a427be329..e413ce7ae 100644 --- a/app/services/blacklight/search_service.rb +++ b/app/services/blacklight/search_service.rb @@ -7,10 +7,10 @@ class SearchService # @params [Blacklight::SearchState] search_state # @params [Class] search_builder_class a class that inherits from Blacklight::SearchBuilder # @params [Hash] context any data the search builder needs to access. For example, the current user. - def initialize(config:, search_state:, search_builder_class: config.search_builder_class, **context) + def initialize(config:, search_state: nil, search_builder_class: config.search_builder_class, **context) @blacklight_config = config @search_state = search_state - @user_params = ActiveSupport::Deprecation::DeprecatedObjectProxy.new(@search_state.params, + @user_params = ActiveSupport::Deprecation::DeprecatedObjectProxy.new(@search_state&.params || {}, 'Use @search_state.params instead of @user_params', Blacklight.deprecation) @search_builder_class = search_builder_class @@ -31,7 +31,7 @@ def search_builder # @return [Blacklight::Solr::Response] the solr response object def search_results(params: nil) unless params - builder = search_builder.with(search_state).page(search_state.page).rows(search_state.per_page) + builder = search_builder.with(search_state).page(search_state&.page).rows(search_state&.per_page) builder = yield(builder) if block_given? end @@ -114,7 +114,7 @@ def opensearch_response(field = nil, extra_controller_params = {}) query = search_builder.with(search_state).merge(solr_opensearch_params(field)).merge(extra_controller_params) response = repository.search(params: query) - [search_state.query_param, response.documents.flat_map { |doc| doc[field] }.uniq] + [search_state&.query_param, response.documents.flat_map { |doc| doc[field] }.uniq] end Blacklight.deprecation.deprecate_methods Blacklight::SearchService, opensearch_response: "The opensearch_response method is deprecated without replacement."