-
Notifications
You must be signed in to change notification settings - Fork 369
/
Copy pathsearch.rb
98 lines (88 loc) · 2.91 KB
/
search.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
require 'chewy/search/scoping'
require 'chewy/search/scrolling'
require 'chewy/search/query_proxy'
require 'chewy/search/parameters'
require 'chewy/search/response'
require 'chewy/search/loader'
require 'chewy/search/request'
require 'chewy/search/pagination/kaminari'
module Chewy
# This module being included to any provides an interface to the
# request DSL. By default it is included to {Chewy::Index}.
#
# The class used as a request DSL provider is
# inherited from {Chewy::Search::Request}
#
# Also, the search class is refined with the pagination module {Chewy::Search::Pagination::Kaminari}.
#
# @example
# PlacesIndex.query(match: {name: 'Moscow'})
# @see Chewy::Index
# @see Chewy::Search::Request
# @see Chewy::Search::ClassMethods
# @see Chewy::Search::Pagination::Kaminari
module Search
extend ActiveSupport::Concern
module ClassMethods
# This is the entry point for the request composition, however,
# most of the {Chewy::Search::Request} methods are delegated
# directly as well.
#
# This method also provides an ability to use names scopes.
#
# @example
# PlacesIndex.all.limit(10)
# # is basically the same as:
# PlacesIndex.limit(10)
# @see Chewy::Search::Request
# @see Chewy::Search::Scoping
# @return [Chewy::Search::Request] request instance
def all
search_class.scopes.last || search_class.new(self)
end
# A simple way to execute search string query.
#
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-uri-request.html
# @return [Hash] the request result
def search_string(query, options = {})
options = options.merge(all.render.slice(:index).merge(q: query))
Chewy.client.search(options)
end
# Delegates methods from the request class to the index class
#
# @example
# PlacesIndex.query(match: {name: 'Moscow'})
def method_missing(name, *args, &block)
if search_class::DELEGATED_METHODS.include?(name)
all.send(name, *args, &block)
else
super
end
end
def respond_to_missing?(name, _)
search_class::DELEGATED_METHODS.include?(name) || super
end
private
def search_class
@search_class ||= build_search_class(Chewy.search_class)
end
def build_search_class(base)
search_class = Class.new(base)
delegate_scoped self, search_class, scopes
const_set('Query', search_class)
end
def delegate_scoped(source, destination, methods)
methods.each do |method|
destination.class_eval do
define_method method do |*args, **kwargs, &block|
scoping do
source.public_send(method, *args, **kwargs, &block)
end
end
method
end
end
end
end
end
end