File tree 4 files changed +81
-3
lines changed
elasticsearch-model/lib/elasticsearch
4 files changed +81
-3
lines changed Original file line number Diff line number Diff line change 4
4
5
5
require 'hashie'
6
6
7
+ require 'elasticsearch/model/adapter'
8
+ require 'elasticsearch/model/adapters/active_record'
9
+
7
10
require 'elasticsearch/model/response'
8
11
require 'elasticsearch/model/response/base'
9
12
require 'elasticsearch/model/response/result'
10
13
require 'elasticsearch/model/response/results'
11
14
require 'elasticsearch/model/response/records'
12
15
require 'elasticsearch/model/searching'
16
+
13
17
require 'elasticsearch/model/version'
14
18
15
19
module Elasticsearch
Original file line number Diff line number Diff line change
1
+ module Elasticsearch
2
+ module Model
3
+ module Adapter
4
+ def from_class ( klass )
5
+ Adapter . new ( klass )
6
+ end
7
+ module_function :from_class
8
+
9
+ class Adapter
10
+
11
+ def initialize ( klass )
12
+ end
13
+
14
+ def response
15
+ Elasticsearch ::Model ::Adapter ::ActiveRecord ::Records
16
+ end
17
+
18
+ end
19
+ end
20
+ end
21
+ end
Original file line number Diff line number Diff line change
1
+ module Elasticsearch
2
+ module Model
3
+ module Adapter
4
+ module ActiveRecord
5
+
6
+ module Records
7
+
8
+ # Return the `ActiveRecord::Relation` instance
9
+ #
10
+ def records
11
+ sql_records = klass . where ( id : @ids )
12
+
13
+ # Re-order records based on the order from Elasticsearch hits
14
+ # by redefining `to_a`, unless the user has called `order()`
15
+ #
16
+ sql_records . instance_exec ( response [ 'hits' ] [ 'hits' ] ) do |hits |
17
+ define_singleton_method :to_a do
18
+ self . load
19
+ @records . sort_by { |record | hits . index { |hit | hit [ '_id' ] == record . id . to_s } }
20
+ end
21
+ end
22
+
23
+ sql_records
24
+ end
25
+
26
+ # Prevent clash with `ActiveSupport::Dependencies::Loadable`
27
+ #
28
+ def load
29
+ records . load
30
+ end
31
+
32
+ # Intercept call to order, so we can ignore the order from Elasticsearch
33
+ #
34
+ def order ( *args )
35
+ sql_records = records . __send__ :order , *args
36
+
37
+ # Redefine the `to_a` method to the original one
38
+ #
39
+ sql_records . instance_exec do
40
+ define_singleton_method ( :to_a ) { self . load ; @records }
41
+ end
42
+
43
+ sql_records
44
+ end
45
+ end
46
+ end
47
+
48
+ end
49
+ end
50
+ end
Original file line number Diff line number Diff line change @@ -7,10 +7,13 @@ class Records
7
7
def initialize ( klass , response )
8
8
super
9
9
@ids = response [ 'hits' ] [ 'hits' ] . map { |hit | hit [ '_id' ] }
10
- end
11
10
12
- def records
13
- @records = klass . find ( @ids )
11
+ # Include module provided by the adapter in the singleton class ("metaclass")
12
+ #
13
+ adapter = Adapter . from_class ( klass )
14
+ metaclass = class << self ; self ; end
15
+ metaclass . __send__ :include , adapter . response
16
+ self
14
17
end
15
18
16
19
# Delegate methods to `@records`
You can’t perform that action at this time.
0 commit comments