Skip to content

Commit

Permalink
Extract SearchBuilder behavior from classes into modules
Browse files Browse the repository at this point in the history
This should help support blacklight generating a search_builder into the
local application:

```ruby
class SearchBuilder
  include Blacklight::SearchBuilder
  include Blacklight::Solr::SearchBuilder
end
```
  • Loading branch information
jcoyne committed Mar 3, 2015
1 parent bf5033e commit d5ed58a
Show file tree
Hide file tree
Showing 6 changed files with 404 additions and 393 deletions.
11 changes: 6 additions & 5 deletions lib/blacklight.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
require 'kaminari'
require 'deprecation'
module Blacklight
autoload :Configurable, 'blacklight/configurable'
autoload :Configuration, 'blacklight/configuration'
autoload :SearchFields, 'blacklight/search_fields'
autoload :SearchBuilder, 'blacklight/search_builder'

autoload :Configurable, 'blacklight/configurable'
autoload :Configuration, 'blacklight/configuration'
autoload :SearchFields, 'blacklight/search_fields'
autoload :SearchBuilder, 'blacklight/search_builder'
autoload :SearchBuilderBehavior, 'blacklight/search_builder_behavior'

autoload :Document, 'blacklight/document'
autoload :Solr, 'blacklight/solr'

Expand Down
127 changes: 1 addition & 126 deletions lib/blacklight/search_builder.rb
Original file line number Diff line number Diff line change
@@ -1,130 +1,5 @@
module Blacklight
class SearchBuilder
extend Deprecation
self.deprecation_horizon = "blacklight 6.0"

attr_reader :processor_chain, :blacklight_params

# @param [List<Symbol>] processor_chain a list of filter methods to run
# @param [Object] scope the scope where the filter methods reside in.
def initialize(processor_chain, scope)
@processor_chain = processor_chain
@scope = scope
@blacklight_params = {}
end

##
# Set the parameters to pass through the processor chain
def with blacklight_params = {}
@blacklight_params = blacklight_params.dup
self
end

##
# Update the :q (query) parameter
def where conditions
@blacklight_params[:q] = conditions
self
end

##
# Append additional processor chain directives
def append *addl_processor_chain
self.class.new(processor_chain + addl_processor_chain, scope).with(blacklight_params)
end

# a solr query method
# @param [Hash,HashWithIndifferentAccess] extra_controller_params (nil) extra parameters to add to the search
# @return [Blacklight::SolrResponse] the solr response object
def query(extra_params = nil)
extra_params ? processed_parameters.merge(extra_params) : processed_parameters
end

# @returns a params hash for searching solr.
# The CatalogController #index action uses this.
# Solr parameters can come from a number of places. From lowest
# precedence to highest:
# 1. General defaults in blacklight config (are trumped by)
# 2. defaults for the particular search field identified by params[:search_field] (are trumped by)
# 3. certain parameters directly on input HTTP query params
# * not just any parameter is grabbed willy nilly, only certain ones are allowed by HTTP input)
# * for legacy reasons, qt in http query does not over-ride qt in search field definition default.
# 4. extra parameters passed in as argument.
#
# spellcheck.q will be supplied with the [:q] value unless specifically
# specified otherwise.
#
# Incoming parameter :f is mapped to :fq solr parameter.
def processed_parameters
Blacklight::Solr::Request.new.tap do |request_parameters|
@processor_chain.each do |method_name|
if scope.respond_to?(method_name, true)
Deprecation.warn Blacklight::SearchBuilder, "Building search parameters by calling #{method_name} on #{scope.class}. This behavior will be deprecated in Blacklight 6.0. Instead, define #{method_name} on a subclass of #{self.class} and set search_builder_class in the configuration"
scope.send(method_name, request_parameters, blacklight_params)
else
send(method_name, request_parameters)
end
end
end
end

def blacklight_config
scope.blacklight_config
end

protected
def page
if blacklight_params[:page].blank?
1
else
blacklight_params[:page].to_i
end
end

def rows default = nil
# default number of rows
rows = default
rows ||= blacklight_config.default_per_page
rows ||= 10

# user-provided parameters should override any default row
rows = blacklight_params[:rows].to_i unless blacklight_params[:rows].blank?
rows = blacklight_params[:per_page].to_i unless blacklight_params[:per_page].blank?

# ensure we don't excede the max page size
rows = blacklight_config.max_per_page if rows.to_i > blacklight_config.max_per_page


rows
end

def sort
field = if blacklight_params[:sort].blank? and sort_field = blacklight_config.default_sort_field
# no sort param provided, use default
sort_field.sort
elsif sort_field = blacklight_config.sort_fields[blacklight_params[:sort]]
# check for sort field key
sort_field.sort
else
# just pass the key through
blacklight_params[:sort]
end

field unless field.blank?
end

def search_field
blacklight_config.search_fields[blacklight_params[:search_field]]
end

def should_add_field_to_request? field_name, field
field.include_in_request || (field.include_in_request.nil? && blacklight_config.add_field_configuration_to_solr_request)
end

protected
def scope
@scope
end

include SearchBuilderBehavior
end
end
130 changes: 130 additions & 0 deletions lib/blacklight/search_builder_behavior.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
module Blacklight
module SearchBuilderBehavior
extend Deprecation
self.deprecation_horizon = "blacklight 6.0"

attr_reader :processor_chain, :blacklight_params

# @param [List<Symbol>] processor_chain a list of filter methods to run
# @param [Object] scope the scope where the filter methods reside in.
def initialize(processor_chain, scope)
@processor_chain = processor_chain
@scope = scope
@blacklight_params = {}
end

##
# Set the parameters to pass through the processor chain
def with blacklight_params = {}
@blacklight_params = blacklight_params.dup
self
end

##
# Update the :q (query) parameter
def where conditions
@blacklight_params[:q] = conditions
self
end

##
# Append additional processor chain directives
def append *addl_processor_chain
self.class.new(processor_chain + addl_processor_chain, scope).with(blacklight_params)
end

# a solr query method
# @param [Hash,HashWithIndifferentAccess] extra_controller_params (nil) extra parameters to add to the search
# @return [Blacklight::SolrResponse] the solr response object
def query(extra_params = nil)
extra_params ? processed_parameters.merge(extra_params) : processed_parameters
end

# @returns a params hash for searching solr.
# The CatalogController #index action uses this.
# Solr parameters can come from a number of places. From lowest
# precedence to highest:
# 1. General defaults in blacklight config (are trumped by)
# 2. defaults for the particular search field identified by params[:search_field] (are trumped by)
# 3. certain parameters directly on input HTTP query params
# * not just any parameter is grabbed willy nilly, only certain ones are allowed by HTTP input)
# * for legacy reasons, qt in http query does not over-ride qt in search field definition default.
# 4. extra parameters passed in as argument.
#
# spellcheck.q will be supplied with the [:q] value unless specifically
# specified otherwise.
#
# Incoming parameter :f is mapped to :fq solr parameter.
def processed_parameters
Blacklight::Solr::Request.new.tap do |request_parameters|
@processor_chain.each do |method_name|
if scope.respond_to?(method_name, true)
Deprecation.warn Blacklight::SearchBuilder, "Building search parameters by calling #{method_name} on #{scope.class}. This behavior will be deprecated in Blacklight 6.0. Instead, define #{method_name} on a subclass of #{self.class} and set search_builder_class in the configuration"
scope.send(method_name, request_parameters, blacklight_params)
else
send(method_name, request_parameters)
end
end
end
end

def blacklight_config
scope.blacklight_config
end

protected
def page
if blacklight_params[:page].blank?
1
else
blacklight_params[:page].to_i
end
end

def rows default = nil
# default number of rows
rows = default
rows ||= blacklight_config.default_per_page
rows ||= 10

# user-provided parameters should override any default row
rows = blacklight_params[:rows].to_i unless blacklight_params[:rows].blank?
rows = blacklight_params[:per_page].to_i unless blacklight_params[:per_page].blank?

# ensure we don't excede the max page size
rows = blacklight_config.max_per_page if rows.to_i > blacklight_config.max_per_page


rows
end

def sort
field = if blacklight_params[:sort].blank? and sort_field = blacklight_config.default_sort_field
# no sort param provided, use default
sort_field.sort
elsif sort_field = blacklight_config.sort_fields[blacklight_params[:sort]]
# check for sort field key
sort_field.sort
else
# just pass the key through
blacklight_params[:sort]
end

field unless field.blank?
end

def search_field
blacklight_config.search_fields[blacklight_params[:search_field]]
end

def should_add_field_to_request? field_name, field
field.include_in_request || (field.include_in_request.nil? && blacklight_config.add_field_configuration_to_solr_request)
end

protected
def scope
@scope
end

end
end
2 changes: 1 addition & 1 deletion lib/blacklight/solr.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ module Blacklight::Solr
autoload :Document, 'blacklight/solr/document'
autoload :Request, 'blacklight/solr/request'
autoload :SearchBuilder, 'blacklight/solr/search_builder'

autoload :SearchBuilderBehavior, 'blacklight/solr/search_builder_behavior'
end
Loading

0 comments on commit d5ed58a

Please sign in to comment.