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,58 @@ 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
29+ index_target ||= options [ :class_name ] . constantize if options [ :class_name ]
30+
31+ strip_pagination_options ( options )
32+ normalize ( options , index_target )
33+ end
34+
35+ FederatedSearchResult . new ( queries , client . multi_search ( queries : cleaned_queries , federation : federation ) )
1336 end
1437
1538 private
1639
1740 def normalize ( options , index_target )
41+ index_target = index_uid_from_target ( index_target )
42+
43+ return nil if index_target . nil?
44+
1845 options
1946 . except ( :class_name )
20- . merge! ( index_uid : index_uid_from_target ( index_target ) )
47+ . merge! ( index_uid : index_target )
2148 end
2249
2350 def index_uid_from_target ( index_target )
2451 case index_target
2552 when String , Symbol
2653 index_target
27- else
28- index_target . index . uid
54+ when Class
55+ if index_target . respond_to? ( :index )
56+ index_target . index . uid
57+ else
58+ Meilisearch ::Rails . logger . warn <<~MODEL_NOT_INDEXED
59+ [meilisearch-rails] This class was passed to a multi/federated search but it does not have an #index: #{ index_target }
60+ [meilisearch-rails] Are you sure it has a `meilisearch` block?
61+ MODEL_NOT_INDEXED
62+
63+ nil
64+ end
2965 end
3066 end
3167
@@ -41,6 +77,20 @@ def paginate(options)
4177 options [ :page ] ||= 1
4278 end
4379
80+ def strip_pagination_options ( options )
81+ pagination_options = %w[ page hitsPerPage hits_per_page limit ] . select do |key |
82+ options . delete ( key ) || options . delete ( key . to_sym )
83+ end
84+
85+ return if pagination_options . empty?
86+
87+ Meilisearch ::Rails . logger . warn <<~WRONG_PAGINATION
88+ [meilisearch-rails] Pagination options in federated search must apply to whole federation.
89+ [meilisearch-rails] These options have been removed: #{ pagination_options . join ( ', ' ) } .
90+ [meilisearch-rails] Please pass them after queries, in the `federation:` option.
91+ WRONG_PAGINATION
92+ end
93+
4494 def pagination_enabled?
4595 Meilisearch ::Rails . configuration [ :pagination_backend ]
4696 end
0 commit comments