Skip to content

Commit

Permalink
Refactor solution
Browse files Browse the repository at this point in the history
  • Loading branch information
Danil Nurgaliev committed Jan 11, 2024
1 parent c02564d commit 636339a
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 33 deletions.
8 changes: 2 additions & 6 deletions lib/chewy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def try_require(path)
require 'chewy/fields/root'
require 'chewy/journal'
require 'chewy/railtie' if defined?(Rails::Railtie)
require 'chewy/elastic_client'

ActiveSupport.on_load(:active_record) do
include Chewy::Index::Observe::ActiveRecordMethods
Expand Down Expand Up @@ -97,12 +98,7 @@ def derive_name(index_name)
# Main elasticsearch-ruby client instance
#
def client
Chewy.current[:chewy_client] ||= begin
client_configuration = configuration.deep_dup
client_configuration.delete(:prefix) # used by Chewy, not relevant to Elasticsearch::Client
block = client_configuration[:transport_options].try(:delete, :proc)
::Elasticsearch::Client.new(client_configuration, &block)
end
Chewy.current[:chewy_client] ||= Chewy::ElasticClient.new(Chewy.current[:chewy_client])
end

# Sends wait_for_status request to ElasticSearch with status
Expand Down
2 changes: 1 addition & 1 deletion lib/chewy/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class Config
# Default field type for any field in any Chewy type. Defaults to 'text'.
:default_field_type,
# Callback called on each search request to be done into ES
:before_search_request_filter
:before_es_request_filter

attr_reader :transport_logger, :transport_tracer,
# Chewy search request DSL base class, used by every index.
Expand Down
29 changes: 29 additions & 0 deletions lib/chewy/elastic_client.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module Chewy
# Replacement for Chewy.client
class ElasticClient
def self.build_es_client(configuration = Chewy.configuration)
client_configuration = configuration.deep_dup
client_configuration.delete(:prefix) # used by Chewy, not relevant to Elasticsearch::Client
block = client_configuration[:transport_options].try(:delete, :proc)
::Elasticsearch::Client.new(client_configuration, &block)
end

def initialize(elastic_client)
@elastic_client = elastic_client || self.class.build_es_client
end

def method_missing(name, *args, **kwargs, &block)
inspect_payload(name, args, kwargs)

@elastic_client.__send__(name, *args, **kwargs, &block)
end

def respond_to_missing?(name, _include_private = false)
@elastic_client.respond_to?(name) || super
end

def inspect_payload(name, args, kwargs)
Chewy.config.before_es_request_filter&.call(name, args, kwargs)
end
end
end
3 changes: 1 addition & 2 deletions lib/chewy/search/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ module Search
# # => <Chewy::Search::Request {:index=>["places"], :body=>{:size=>20}}>
# scope.order(:name).offset(10)
# # => <Chewy::Search::Request {:index=>["places"], :body=>{:sort=>["name"], :from=>10}}>
class Request # rubocop:disable Metrics/ClassLength
class Request
include Enumerable
include Scoping
include Scrolling
Expand Down Expand Up @@ -1034,7 +1034,6 @@ def reset
def perform(additional = {})
request_body = render.merge(additional)
ActiveSupport::Notifications.instrument 'search_query.chewy', notification_payload(request: request_body) do
Chewy.config.before_search_request_filter&.call(request_body)
Chewy.client.search(request_body)
rescue Elasticsearch::Transport::Transport::Errors::NotFound
{}
Expand Down
19 changes: 19 additions & 0 deletions spec/chewy/before_search_request_filter_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
require 'spec_helper'

describe 'Before search request filter' do
let(:filter) { instance_double('Proc') }
let!(:filter_previous_value) { Chewy.before_es_request_filter }

before do
Chewy.before_es_request_filter = filter
end

after do
Chewy.before_es_request_filter = filter_previous_value
end

it 'call filter with the request body' do
expect(filter).to receive(:call).with(:search, [{body: {size: 0}, index: ['products']}], {})
Chewy.client.search({index: ['products'], body: {size: 0}}).to_a
end
end
20 changes: 0 additions & 20 deletions spec/chewy/search/request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -878,25 +878,5 @@
end.to change(query, :performed?).from(false).to(true)
end
end

describe 'before_search_request_filter' do
let(:query) { ProductsIndex.limit(0) }
let(:raw_response) { Chewy.client.search(query.render) }
let(:filter) { instance_double('Proc') }
let!(:filter_previous_value) { Chewy.before_search_request_filter }

before do
Chewy.before_search_request_filter = filter
end

after do
Chewy.before_search_request_filter = filter_previous_value
end

it 'call filter with the request body' do
expect(filter).to receive(:call).with({body: {size: 0}, index: ['products']})
query.response
end
end
end
end
11 changes: 7 additions & 4 deletions spec/chewy_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,21 @@

before do
Chewy.current[:chewy_client] = nil
allow(Chewy).to receive_messages(configuration: {transport_options: {proc: faraday_block}})
end

specify do
expect(Chewy).to receive_messages(configuration: {transport_options: {proc: faraday_block}})

allow(Elasticsearch::Client).to receive(:new).with(expected_client_config) do |*_args, &passed_block|
expect(Elasticsearch::Client).to receive(:new).with(expected_client_config) do |*_args, &passed_block|
# RSpec's `with(..., &block)` was used previously, but doesn't actually do
# any verification of the passed block (even of its presence).
expect(passed_block.source_location).to eq(faraday_block.source_location)

mock_client
end
end

its(:client) { is_expected.to eq(mock_client) }
expect(Chewy.client).to be_a(Chewy::ElasticClient)
end

after { Chewy.current[:chewy_client] = initial_client }
end
Expand Down

0 comments on commit 636339a

Please sign in to comment.