1- require_relative 'multi_search/result'
1+ require_relative 'multi_search/multi_search_result'
2+ require_relative 'multi_search/federated_search_result'
23
34module Meilisearch
45 module Rails
@@ -9,23 +10,59 @@ def multi_search(searches)
910 normalize ( options , index_target )
1011 end
1112
12- MultiSearchResult . new ( searches , client . multi_search ( search_parameters ) )
13+ MultiSearchResult . new ( searches , client . multi_search ( queries : search_parameters ) )
14+ end
15+
16+ def federated_search ( queries :, federation : { } )
17+ if federation . nil?
18+ Meilisearch ::Rails . logger . warn (
19+ '[meilisearch-rails] In federated_search, `nil` is an invalid `:federation` option. To explicitly use defaults, pass `{}`.'
20+ )
21+
22+ federation = { }
23+ end
24+
25+ queries . map! { |item | [ nil , item ] } if queries . is_a? ( Array )
26+
27+ cleaned_queries = queries . filter_map do |( index_target , options ) |
28+ index_target = options . delete ( :index_uid ) || index_target || options [ :class_name ] &.constantize
29+
30+ strip_pagination_options ( options )
31+ normalize ( options , index_target )
32+ end
33+
34+ raw_results = client . multi_search ( queries : cleaned_queries , federation : federation )
35+
36+ FederatedSearchResult . new ( queries , raw_results )
1337 end
1438
1539 private
1640
1741 def normalize ( options , index_target )
42+ index_target = index_uid_from_target ( index_target )
43+
44+ return nil if index_target . nil?
45+
1846 options
1947 . except ( :class_name )
20- . merge! ( index_uid : index_uid_from_target ( index_target ) )
48+ . merge! ( index_uid : index_target )
2149 end
2250
2351 def index_uid_from_target ( index_target )
2452 case index_target
2553 when String , Symbol
2654 index_target
27- else
28- index_target . index . uid
55+ when Class
56+ if index_target . respond_to? ( :index )
57+ index_target . index . uid
58+ else
59+ Meilisearch ::Rails . logger . warn <<~MODEL_NOT_INDEXED
60+ [meilisearch-rails] This class was passed to a multi/federated search but it does not have an #index: #{ index_target }
61+ [meilisearch-rails] Are you sure it has a `meilisearch` block?
62+ MODEL_NOT_INDEXED
63+
64+ nil
65+ end
2966 end
3067 end
3168
@@ -41,6 +78,20 @@ def paginate(options)
4178 options [ :page ] ||= 1
4279 end
4380
81+ def strip_pagination_options ( options )
82+ pagination_options = %w[ page hitsPerPage hits_per_page limit offset ] . select do |key |
83+ options . delete ( key ) || options . delete ( key . to_sym )
84+ end
85+
86+ return if pagination_options . empty?
87+
88+ Meilisearch ::Rails . logger . warn <<~WRONG_PAGINATION
89+ [meilisearch-rails] Pagination options in federated search must apply to whole federation.
90+ [meilisearch-rails] These options have been removed: #{ pagination_options . join ( ', ' ) } .
91+ [meilisearch-rails] Please pass them after queries, in the `federation:` option.
92+ WRONG_PAGINATION
93+ end
94+
4495 def pagination_enabled?
4596 Meilisearch ::Rails . configuration [ :pagination_backend ]
4697 end
0 commit comments