meilisearch-rails 0.14.3 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: babcf0719c23af9294b52e76c7549cacf9baeb578221c18cf2be53db5bbeaaa1
4
- data.tar.gz: 33aee866b13502a67657a5803d395fbcebe737456e2f45e812b1312074b5b7df
3
+ metadata.gz: 317b4503e3616fe8f309ac194c2eb85a902222edda8ae58824c53f081280a0de
4
+ data.tar.gz: f9ef605f39f533307b5af4d6204c8fd19fb5d49dd507e72010d7d5458b37e066
5
5
  SHA512:
6
- metadata.gz: 230fc45c263f5aa10ff137eba952673eed221a33bae3ae1c5cb7cfe35adbdc50d9399feaeaf20c7766fd78bf0c29ed440de08880de8f5c2e9d7889bcf6d107c5
7
- data.tar.gz: 18bbbc7a7fd9cb64bf1f2429234c10c56b1c3c88a044909a3b01f1e4ceb276449f61cc6ceb52148131c44b8d5dfbeeb09438953dff15ff9857b3d9e7864e2ccd
6
+ metadata.gz: 1f2d3137a16b624704eeadb64d86c32e0c87864abf7af1fb7df19d8acf90d74ee57db5df1707c073c80a73aec99964519bcace556a6ce8f40828d179b74971f4
7
+ data.tar.gz: 0a56e1651b062fc45fcde8e4206d2f08c21af07882bfaaeb80d928fe3cf4fa112a5e2102127f7d598120c978076bbacf2c2681c2452cca0406ac5ac15a899d2a
data/README.md CHANGED
@@ -38,6 +38,7 @@
38
38
  - [⚙️ Settings](#️-settings)
39
39
  - [🔍 Custom search](#-custom-search)
40
40
  - [🔍🔍 Multi search](#-multi-search)
41
+ - [🔍🔍 Federated search](#-federated-search)
41
42
  - [🪛 Options](#-options)
42
43
  - [Meilisearch configuration & environment](#meilisearch-configuration--environment)
43
44
  - [Pagination with `kaminari` or `will_paginate`](#backend-pagination-with-kaminari-or-will_paginate-)
@@ -98,7 +99,7 @@ gem 'meilisearch-rails'
98
99
  Create a new file `config/initializers/meilisearch.rb` to setup your `MEILISEARCH_HOST` and `MEILISEARCH_API_KEY`
99
100
 
100
101
  ```ruby
101
- MeiliSearch::Rails.configuration = {
102
+ Meilisearch::Rails.configuration = {
102
103
  meilisearch_url: ENV.fetch('MEILISEARCH_HOST', 'http://localhost:7700'),
103
104
  meilisearch_api_key: ENV.fetch('MEILISEARCH_API_KEY', 'YourMeilisearchAPIKey')
104
105
  }
@@ -120,7 +121,7 @@ The following code will create a `Book` index and add search capabilities to you
120
121
 
121
122
  ```ruby
122
123
  class Book < ActiveRecord::Base
123
- include MeiliSearch::Rails
124
+ include Meilisearch::Rails
124
125
 
125
126
  meilisearch do
126
127
  attribute :title, :author # only the attributes 'title', and 'author' will be sent to Meilisearch
@@ -154,7 +155,7 @@ Requests made to Meilisearch may timeout and retry. To adapt the behavior to
154
155
  your needs, you can change the parameters during configuration:
155
156
 
156
157
  ```ruby
157
- MeiliSearch::Rails.configuration = {
158
+ Meilisearch::Rails.configuration = {
158
159
  meilisearch_url: 'YourMeilisearchUrl',
159
160
  meilisearch_api_key: 'YourMeilisearchAPIKey',
160
161
  timeout: 2,
@@ -172,7 +173,7 @@ You can configure the index settings by adding them inside the `meilisearch` blo
172
173
 
173
174
  ```ruby
174
175
  class Book < ApplicationRecord
175
- include MeiliSearch::Rails
176
+ include Meilisearch::Rails
176
177
 
177
178
  meilisearch do
178
179
  searchable_attributes [:title, :author, :publisher, :description]
@@ -235,7 +236,7 @@ Book.search('*', sort: ['title:asc'])
235
236
  Meilisearch supports searching multiple models at the same time (see [🔍 Custom search](#-custom-search) for search options):
236
237
 
237
238
  ```ruby
238
- multi_search_results = MeiliSearch::Rails.multi_search(
239
+ multi_search_results = Meilisearch::Rails.multi_search(
239
240
  Book => { q: 'Harry' },
240
241
  Manga => { q: 'Attack' }
241
242
  )
@@ -265,12 +266,14 @@ Use `#each_result` to loop through pairs of your provided keys and the results:
265
266
  </ul>
266
267
  ```
267
268
 
268
- Records are loaded when the keys are models, or when `:class_name` option is passed:
269
+ Records are loaded when the keys are models, or when `:scope` option is passed:
269
270
 
270
271
  ```ruby
271
- multi_search_results = MeiliSearch::Rails.multi_search(
272
- 'books' => { q: 'Harry', class_name: 'Book' },
273
- 'mangas' => { q: 'Attack', class_name: 'Manga' }
272
+ multi_search_results = Meilisearch::Rails.multi_search(
273
+ # scope may be a relation
274
+ 'books' => { q: 'Harry', scope: Book.all },
275
+ # or a model
276
+ 'mangas' => { q: 'Attack', scope: Manga }
274
277
  )
275
278
  ```
276
279
 
@@ -279,9 +282,9 @@ Otherwise, hashes are returned.
279
282
  The index to search is inferred from the model if the key is a model, if the key is a string the key is assumed to be the index unless the `:index_uid` option is passed:
280
283
 
281
284
  ```ruby
282
- multi_search_results = MeiliSearch::Rails.multi_search(
283
- 'western' => { q: 'Harry', class_name: 'Book', index_uid: 'books_production' },
284
- 'japanese' => { q: 'Attack', class_name: 'Manga', index_uid: 'mangas_production' }
285
+ multi_search_results = Meilisearch::Rails.multi_search(
286
+ 'western' => { q: 'Harry', scope: Book, index_uid: 'books_production' },
287
+ 'japanese' => { q: 'Attack', scope: Manga, index_uid: 'mangas_production' }
285
288
  )
286
289
  ```
287
290
 
@@ -291,10 +294,11 @@ You can search the same index multiple times by specifying `:index_uid`:
291
294
 
292
295
  ```ruby
293
296
  query = 'hero'
294
- multi_search_results = MeiliSearch::Rails.multi_search(
295
- 'Isekai Manga' => { q: query, class_name: 'Manga', filters: 'genre:isekai', index_uid: 'mangas_production' }
296
- 'Shounen Manga' => { q: query, class_name: 'Manga', filters: 'genre:shounen', index_uid: 'mangas_production' }
297
- 'Steampunk Manga' => { q: query, class_name: 'Manga', filters: 'genre:steampunk', index_uid: 'mangas_production' }
297
+
298
+ multi_search_results = Meilisearch::Rails.multi_search(
299
+ 'Isekai Manga' => { q: query, scope: Manga, filters: 'genre:isekai', index_uid: 'mangas_production' }
300
+ 'Shounen Manga' => { q: query, scope: Manga, filters: 'genre:shounen', index_uid: 'mangas_production' }
301
+ 'Steampunk Manga' => { q: query, scope: Manga, filters: 'genre:steampunk', index_uid: 'mangas_production' }
298
302
  )
299
303
  ```
300
304
 
@@ -320,6 +324,172 @@ But this has been deprecated in favor of **federated search**.
320
324
 
321
325
  See the [official multi search documentation](https://www.meilisearch.com/docs/reference/api/multi_search).
322
326
 
327
+ ## 🔍🔍 Federated search
328
+
329
+ Federated search is similar to multi search, except that results are not grouped but sorted by ranking rules.
330
+
331
+ ```ruby
332
+ results = Meilisearch::Rails.federated_search(
333
+ queries: [
334
+ { q: 'Harry', scope: Book.all },
335
+ { q: 'Attack on Titan', scope: Manga.all }
336
+ ]
337
+ )
338
+ ```
339
+
340
+ An enumerable `FederatedSearchResult` is returned, which can be iterated through with `#each`:
341
+
342
+ ```erb
343
+ <ul>
344
+ <% results.each do |record| %>
345
+ <li><%= record.title %></li>
346
+ <% end %>
347
+ </ul>
348
+
349
+
350
+ <ul>
351
+ <!-- Attack on Titan appears first even though it was specified second,
352
+ it's ranked higher because it's a closer match -->
353
+ <li>Attack on Titan</li>
354
+ <li>Harry Potter and the Philosopher's Stone</li>
355
+ <li>Harry Potter and the Chamber of Secrets</li>
356
+ </ul>
357
+ ```
358
+
359
+ The `queries` parameter may be a multi-search style hash with keys that are either classes, index names, or neither:
360
+
361
+ ```ruby
362
+ results = Meilisearch::Rails.federated_search(
363
+ queries: {
364
+ Book => { q: 'Harry' },
365
+ Manga => { q: 'Attack on Titan' }
366
+ }
367
+ )
368
+ ```
369
+
370
+ ```ruby
371
+ results = Meilisearch::Rails.federated_search(
372
+ queries: {
373
+ 'books_production' => { q: 'Harry', scope: Book.all },
374
+ 'mangas_production' => { q: 'Attack on Titan', scope: Manga.all }
375
+ }
376
+ )
377
+ ```
378
+
379
+ ```ruby
380
+ results = Meilisearch::Rails.federated_search(
381
+ queries: {
382
+ 'potter' => { q: 'Harry', scope: Book.all, index_uid: 'books_production' },
383
+ 'titan' => { q: 'Attack on Titan', scope: Manga.all, index_uid: 'mangas_production' }
384
+ }
385
+ )
386
+ ```
387
+
388
+ ### Loading records <!-- omit in toc -->
389
+
390
+ Records are loaded when the `:scope` option is passed (may be a model or a relation),
391
+ or when a hash query is used with models as keys:
392
+
393
+ ```ruby
394
+ results = Meilisearch::Rails.federated_search(
395
+ queries: [
396
+ { q: 'Harry', scope: Book },
397
+ { q: 'Attack on Titan', scope: Manga },
398
+ ]
399
+ )
400
+ ```
401
+
402
+ ```ruby
403
+ results = Meilisearch::Rails.federated_search(
404
+ queries: {
405
+ Book => { q: 'Harry' },
406
+ Manga => { q: 'Attack on Titan' }
407
+ }
408
+ )
409
+ ```
410
+
411
+ If the model is not provided, hashes are returned!
412
+
413
+ ### Scoping records <!-- omit in toc -->
414
+
415
+ Any relation passed as `:scope` is used as the starting point when loading records:
416
+
417
+ ```ruby
418
+ results = Meilisearch::Rails.federated_search(
419
+ queries: [
420
+ { q: 'Harry', scope: Book.where('year <= 2006') },
421
+ { q: 'Attack on Titan', scope: Manga.where(author: Author.find_by(name: 'Iseyama')) },
422
+ ]
423
+ )
424
+ ```
425
+
426
+ ### Specifying the search index <!-- omit in toc -->
427
+
428
+ In order of precedence, to figure out which index to search, Meilisearch Rails will check:
429
+
430
+ 1. `index_uid` options
431
+ ```ruby
432
+ results = Meilisearch::Rails.federated_search(
433
+ queries: [
434
+ # Searching the 'fantasy_books' index
435
+ { q: 'Harry', scope: Book, index_uid: 'fantasy_books' },
436
+ ]
437
+ )
438
+ ```
439
+ 2. The index associated with the model
440
+ ```ruby
441
+ results = Meilisearch::Rails.federated_search(
442
+ queries: [
443
+ # Searching the index associated with the Book model
444
+ # i. e. Book.index.uid
445
+ { q: 'Harry', scope: Book },
446
+ ]
447
+ )
448
+ ```
449
+ 3. The key when using hash queries
450
+ ```ruby
451
+ results = Meilisearch::Rails.federated_search(
452
+ queries: {
453
+ # Searching index 'books_production'
454
+ books_production: { q: 'Harry', scope: Book },
455
+ }
456
+ )
457
+ ```
458
+
459
+ ### Pagination and other options <!-- omit in toc -->
460
+
461
+ In addition to queries, federated search also accepts `:federation` parameters which allow for finer control of the search:
462
+
463
+ ```ruby
464
+ results = Meilisearch::Rails.federated_search(
465
+ queries: [
466
+ { q: 'Harry', scope: Book },
467
+ { q: 'Attack on Titan', scope: Manga },
468
+ ],
469
+ federation: { offset: 10, limit: 5 }
470
+ )
471
+ ```
472
+ See a full list of accepted options in [the meilisearch documentation](https://www.meilisearch.com/docs/reference/api/multi_search#federation).
473
+
474
+ #### Metadata <!-- omit in toc -->
475
+
476
+ The returned result from a federated search includes a `.metadata` attribute you can use to access everything other than the search hits:
477
+
478
+ ```ruby
479
+ result.metadata
480
+ # {
481
+ # "processingTimeMs" => 0,
482
+ # "limit" => 20,
483
+ # "offset" => 0,
484
+ # "estimatedTotalHits" => 2,
485
+ # "semanticHitCount": 0
486
+ # }
487
+ ```
488
+
489
+ The metadata contains facet stats and pagination stats, among others. See the full response in [the documentation](https://www.meilisearch.com/docs/reference/api/multi_search#federated-multi-search-requests).
490
+
491
+ More details on federated search (such as available `federation:` options) can be found on [the official multi search documentation](https://www.meilisearch.com/docs/reference/api/multi_search).
492
+
323
493
  ## 🪛 Options
324
494
 
325
495
  ### Meilisearch configuration & environment
@@ -333,7 +503,7 @@ This gem supports:
333
503
  Specify the `:pagination_backend` in the configuration file:
334
504
 
335
505
  ```ruby
336
- MeiliSearch::Rails.configuration = {
506
+ Meilisearch::Rails.configuration = {
337
507
  meilisearch_url: 'YourMeilisearchUrl',
338
508
  meilisearch_api_key: 'YourMeilisearchAPIKey',
339
509
  pagination_backend: :kaminari # :will_paginate
@@ -382,7 +552,7 @@ Then in your model you must extend `Pagy::Meilisearch`:
382
552
 
383
553
  ```rb
384
554
  class Book < ApplicationRecord
385
- include MeiliSearch::Rails
555
+ include Meilisearch::Rails
386
556
  extend Pagy::Meilisearch
387
557
 
388
558
  meilisearch # ...
@@ -403,7 +573,7 @@ end
403
573
  <%== pagy_nav(@pagy) %>
404
574
  ```
405
575
 
406
- :warning: There is no need to set `pagination_backend` in the configuration block `MeiliSearch::Rails.configuration` for `pagy`.
576
+ :warning: There is no need to set `pagination_backend` in the configuration block `Meilisearch::Rails.configuration` for `pagy`.
407
577
 
408
578
  Check [`ddnexus/pagy`](https://ddnexus.github.io/pagy/extras/meilisearch) for more information.
409
579
 
@@ -415,7 +585,7 @@ you have multiple ways to achieve this.
415
585
  By adding `active: false` in the configuration initializer:
416
586
 
417
587
  ```ruby
418
- MeiliSearch::Rails.configuration = {
588
+ Meilisearch::Rails.configuration = {
419
589
  meilisearch_url: 'YourMeilisearchUrl',
420
590
  meilisearch_api_key: 'YourMeilisearchAPIKey',
421
591
  active: false
@@ -425,11 +595,11 @@ MeiliSearch::Rails.configuration = {
425
595
  Or you can disable programmatically:
426
596
 
427
597
  ```ruby
428
- MeiliSearch::Rails.deactivate! # all the following HTTP calls will be dismissed.
598
+ Meilisearch::Rails.deactivate! # all the following HTTP calls will be dismissed.
429
599
 
430
600
  # or you can pass a block to it:
431
601
 
432
- MeiliSearch::Rails.deactivate! do
602
+ Meilisearch::Rails.deactivate! do
433
603
  # every Meilisearch call here will be dismissed, no error will be raised.
434
604
  # after the block, Meilisearch state will be active.
435
605
  end
@@ -438,7 +608,7 @@ end
438
608
  You can also activate if you deactivated earlier:
439
609
 
440
610
  ```ruby
441
- MeiliSearch::Rails.activate!
611
+ Meilisearch::Rails.activate!
442
612
  ```
443
613
 
444
614
  :warning: These calls are persistent, so prefer to use the method with the block. This way, you will not forget to activate it afterward.
@@ -449,7 +619,7 @@ By default, the **index_uid** will be the class name, e.g. `Book`. You can custo
449
619
 
450
620
  ```ruby
451
621
  class Book < ActiveRecord::Base
452
- include MeiliSearch::Rails
622
+ include Meilisearch::Rails
453
623
 
454
624
  meilisearch index_uid: 'MyCustomUID'
455
625
  end
@@ -460,7 +630,7 @@ end
460
630
  You can suffix the index UID with the current Rails environment by setting it globally:
461
631
 
462
632
  ```ruby
463
- MeiliSearch::Rails.configuration = {
633
+ Meilisearch::Rails.configuration = {
464
634
  meilisearch_url: 'YourMeilisearchUrl',
465
635
  meilisearch_api_key: 'YourMeilisearchAPIKey',
466
636
  per_environment: true
@@ -479,7 +649,7 @@ You can add a custom attribute by using the `add_attribute` option or by using a
479
649
 
480
650
  ```ruby
481
651
  class Author < ApplicationRecord
482
- include MeiliSearch::Rails
652
+ include Meilisearch::Rails
483
653
 
484
654
  meilisearch do
485
655
  attribute :first_name, :last_name
@@ -511,7 +681,7 @@ Note that the primary key must return a **unique value** otherwise your data cou
511
681
 
512
682
  ```ruby
513
683
  class Book < ActiveRecord::Base
514
- include MeiliSearch::Rails
684
+ include Meilisearch::Rails
515
685
 
516
686
  meilisearch primary_key: :isbn # isbn is a column in your table definition.
517
687
  end
@@ -522,7 +692,7 @@ will be used as the reference to the document when Meilisearch needs it.
522
692
 
523
693
  ```rb
524
694
  class Book < ActiveRecord::Base
525
- include MeiliSearch::Rails
695
+ include Meilisearch::Rails
526
696
 
527
697
  meilisearch primary_key: :my_custom_ms_id
528
698
 
@@ -541,7 +711,7 @@ As soon as you use those constraints, `add_documents` and `delete_documents` cal
541
711
 
542
712
  ```ruby
543
713
  class Book < ActiveRecord::Base
544
- include MeiliSearch::Rails
714
+ include Meilisearch::Rails
545
715
 
546
716
  meilisearch if: :published?, unless: :premium?
547
717
 
@@ -564,7 +734,7 @@ You can index a record in several indexes using the `add_index` option:
564
734
 
565
735
  ```ruby
566
736
  class Book < ActiveRecord::Base
567
- include MeiliSearch::Rails
737
+ include Meilisearch::Rails
568
738
 
569
739
  PUBLIC_INDEX_UID = 'Books'
570
740
  SECURED_INDEX_UID = 'PrivateBooks'
@@ -593,7 +763,7 @@ You may want to share an index between several models. You'll need to ensure you
593
763
 
594
764
  ```ruby
595
765
  class Cat < ActiveRecord::Base
596
- include MeiliSearch::Rails
766
+ include Meilisearch::Rails
597
767
 
598
768
  meilisearch index_uid: 'Animals', primary_key: :ms_id
599
769
 
@@ -605,7 +775,7 @@ class Cat < ActiveRecord::Base
605
775
  end
606
776
 
607
777
  class Dog < ActiveRecord::Base
608
- include MeiliSearch::Rails
778
+ include Meilisearch::Rails
609
779
 
610
780
  meilisearch index_uid: 'Animals', primary_key: :ms_id
611
781
 
@@ -623,7 +793,7 @@ You can configure the auto-indexing & auto-removal process to use a queue to per
623
793
 
624
794
  ```ruby
625
795
  class Book < ActiveRecord::Base
626
- include MeiliSearch::Rails
796
+ include Meilisearch::Rails
627
797
 
628
798
  meilisearch enqueue: true # ActiveJob will be triggered using a `meilisearch` queue
629
799
  end
@@ -637,7 +807,7 @@ With **ActiveJob**:
637
807
 
638
808
  ```ruby
639
809
  class Book < ActiveRecord::Base
640
- include MeiliSearch::Rails
810
+ include Meilisearch::Rails
641
811
 
642
812
  meilisearch enqueue: :trigger_job do
643
813
  attribute :title, :author, :description
@@ -667,7 +837,7 @@ With [**Sidekiq**](https://github.com/mperham/sidekiq):
667
837
 
668
838
  ```ruby
669
839
  class Book < ActiveRecord::Base
670
- include MeiliSearch::Rails
840
+ include Meilisearch::Rails
671
841
 
672
842
  meilisearch enqueue: :trigger_sidekiq_job do
673
843
  attribute :title, :author, :description
@@ -697,7 +867,7 @@ With [**DelayedJob**](https://github.com/collectiveidea/delayed_job):
697
867
 
698
868
  ```ruby
699
869
  class Book < ActiveRecord::Base
700
- include MeiliSearch::Rails
870
+ include Meilisearch::Rails
701
871
 
702
872
  meilisearch enqueue: :trigger_delayed_job do
703
873
  attribute :title, :author, :description
@@ -721,7 +891,7 @@ Extend a change to a related record.
721
891
 
722
892
  ```ruby
723
893
  class Author < ActiveRecord::Base
724
- include MeiliSearch::Rails
894
+ include Meilisearch::Rails
725
895
 
726
896
  has_many :books
727
897
  # If your association uses belongs_to
@@ -731,7 +901,7 @@ class Author < ActiveRecord::Base
731
901
  end
732
902
 
733
903
  class Book < ActiveRecord::Base
734
- include MeiliSearch::Rails
904
+ include Meilisearch::Rails
735
905
 
736
906
  belongs_to :author
737
907
  after_touch :index!
@@ -750,7 +920,7 @@ With **Sequel**, you can use the `touch` plugin to propagate changes.
750
920
  ```ruby
751
921
  # app/models/author.rb
752
922
  class Author < Sequel::Model
753
- include MeiliSearch::Rails
923
+ include Meilisearch::Rails
754
924
 
755
925
  one_to_many :books
756
926
 
@@ -772,7 +942,7 @@ end
772
942
 
773
943
  # app/models/book.rb
774
944
  class Book < Sequel::Model
775
- include MeiliSearch::Rails
945
+ include Meilisearch::Rails
776
946
 
777
947
  many_to_one :author
778
948
  after_touch :index!
@@ -795,7 +965,7 @@ You can strip all HTML tags from your attributes with the `sanitize` option.
795
965
 
796
966
  ```ruby
797
967
  class Book < ActiveRecord::Base
798
- include MeiliSearch::Rails
968
+ include Meilisearch::Rails
799
969
 
800
970
  meilisearch sanitize: true
801
971
  end
@@ -807,7 +977,7 @@ You can force the UTF-8 encoding of all your attributes using the `force_utf8_en
807
977
 
808
978
  ```ruby
809
979
  class Book < ActiveRecord::Base
810
- include MeiliSearch::Rails
980
+ include Meilisearch::Rails
811
981
 
812
982
  meilisearch force_utf8_encoding: true
813
983
  end
@@ -819,7 +989,7 @@ You can eager load associations using `meilisearch_import` scope.
819
989
 
820
990
  ```ruby
821
991
  class Author < ActiveRecord::Base
822
- include MeiliSearch::Rails
992
+ include Meilisearch::Rails
823
993
 
824
994
  has_many :books
825
995
 
@@ -872,7 +1042,7 @@ You can disable exceptions that could be raised while trying to reach Meilisearc
872
1042
 
873
1043
  ```ruby
874
1044
  class Book < ActiveRecord::Base
875
- include MeiliSearch::Rails
1045
+ include Meilisearch::Rails
876
1046
 
877
1047
  # Only raise exceptions in development environment.
878
1048
  meilisearch raise_on_failure: Rails.env.development?
@@ -887,7 +1057,7 @@ You can force indexing and removing to be synchronous by setting the following o
887
1057
 
888
1058
  ```ruby
889
1059
  class Book < ActiveRecord::Base
890
- include MeiliSearch::Rails
1060
+ include Meilisearch::Rails
891
1061
 
892
1062
  meilisearch synchronous: true
893
1063
  end
@@ -900,7 +1070,7 @@ You can disable auto-indexing and auto-removing setting the following options:
900
1070
 
901
1071
  ```ruby
902
1072
  class Book < ActiveRecord::Base
903
- include MeiliSearch::Rails
1073
+ include Meilisearch::Rails
904
1074
 
905
1075
  meilisearch auto_index: false, auto_remove: false
906
1076
  end
@@ -1,4 +1,4 @@
1
- module MeiliSearch
1
+ module Meilisearch
2
2
  module Rails
3
3
  module Configuration
4
4
  def configuration
@@ -44,11 +44,11 @@ module MeiliSearch
44
44
  def client
45
45
  return black_hole unless active?
46
46
 
47
- ::MeiliSearch::Client.new(
47
+ ::Meilisearch::Client.new(
48
48
  configuration[:meilisearch_url] || 'http://localhost:7700',
49
49
  configuration[:meilisearch_api_key],
50
50
  configuration.slice(:timeout, :max_retries)
51
- .merge(client_agents: MeiliSearch::Rails.qualified_version)
51
+ .merge(client_agents: Meilisearch::Rails.qualified_version)
52
52
  )
53
53
  end
54
54
  end
@@ -1,4 +1,4 @@
1
- module MeiliSearch
1
+ module Meilisearch
2
2
  module Rails
3
3
  class NoBlockGiven < StandardError; end
4
4
 
@@ -6,7 +6,7 @@ module MeiliSearch
6
6
 
7
7
  class NotConfigured < StandardError
8
8
  def message
9
- 'Please configure Meilisearch. Set MeiliSearch::Rails.configuration = ' \
9
+ 'Please configure Meilisearch. Set Meilisearch::Rails.configuration = ' \
10
10
  "{meilisearch_url: 'YOUR_MEILISEARCH_URL', meilisearch_api_key: 'YOUR_API_KEY'}"
11
11
  end
12
12
  end
@@ -1,11 +1,11 @@
1
- module MeiliSearch
1
+ module Meilisearch
2
2
  module Rails
3
3
  class MSCleanUpJob < ::ActiveJob::Base
4
4
  queue_as :meilisearch
5
5
 
6
6
  def perform(documents)
7
7
  documents.each do |document|
8
- index = MeiliSearch::Rails.client.index(document[:index_uid])
8
+ index = Meilisearch::Rails.client.index(document[:index_uid])
9
9
 
10
10
  if document[:synchronous]
11
11
  index.delete_document(document[:primary_key]).await
@@ -1,4 +1,4 @@
1
- module MeiliSearch
1
+ module Meilisearch
2
2
  module Rails
3
3
  class MSJob < ::ActiveJob::Base
4
4
  queue_as :meilisearch
@@ -0,0 +1,78 @@
1
+ require 'active_support/core_ext/module/delegation'
2
+
3
+ module Meilisearch
4
+ module Rails
5
+ class FederatedSearchResult
6
+ attr_reader :metadata, :hits
7
+
8
+ def initialize(searches, raw_results)
9
+ hits = raw_results.delete('hits')
10
+ @hits = load_hits(hits, searches.to_a)
11
+ @metadata = raw_results
12
+ end
13
+
14
+ include Enumerable
15
+
16
+ delegate :each, :to_a, :to_ary, :empty?, :[], :first, :last, to: :@hits
17
+
18
+ private
19
+
20
+ def load_hits(hits, searches)
21
+ hits_by_pos = hits.group_by { |hit| hit['_federation']['queriesPosition'] }
22
+
23
+ keys_and_records_by_pos = hits_by_pos.to_h do |pos, group_hits|
24
+ search_target, search_opts = searches[pos]
25
+
26
+ scope = if search_opts[:scope]
27
+ search_opts[:scope]
28
+ elsif search_target.instance_of?(Class)
29
+ search_target
30
+ end
31
+
32
+ if scope.present?
33
+ [pos, load_results(scope, group_hits)]
34
+ else
35
+ [pos, [nil, group_hits]]
36
+ end
37
+ end
38
+
39
+ hits.filter_map do |hit|
40
+ hit_cond_key, recs_by_id = keys_and_records_by_pos[hit['_federation']['queriesPosition']]
41
+
42
+ if hit_cond_key.present?
43
+ record = recs_by_id[hit[hit_cond_key.to_s].to_s]
44
+ record&.formatted = hit['_formatted']
45
+ record
46
+ else
47
+ hit
48
+ end
49
+ end
50
+ end
51
+
52
+ def load_results(scope, hits)
53
+ klass = scope.respond_to?(:model) ? scope.model : scope
54
+
55
+ pk_method = klass.ms_primary_key_method
56
+ pk_method = pk_method.in if Utilities.mongo_model?(klass)
57
+
58
+ condition_key = pk_is_virtual?(klass, pk_method) ? klass.primary_key : pk_method
59
+
60
+ hits_by_id = hits.index_by { |hit| hit[condition_key.to_s] }
61
+
62
+ records = scope.where(condition_key => hits_by_id.keys)
63
+
64
+ results_by_id = records.index_by do |record|
65
+ record.send(condition_key).to_s
66
+ end
67
+
68
+ [condition_key, results_by_id]
69
+ end
70
+
71
+ def pk_is_virtual?(model_class, pk_method)
72
+ model_class.columns
73
+ .map(&(Utilities.sequel_model?(model_class) ? :to_s : :name))
74
+ .exclude?(pk_method.to_s)
75
+ end
76
+ end
77
+ end
78
+ end
@@ -1,4 +1,4 @@
1
- module MeiliSearch
1
+ module Meilisearch
2
2
  module Rails
3
3
  class MultiSearchResult
4
4
  attr_reader :metadata
@@ -9,12 +9,18 @@ module MeiliSearch
9
9
 
10
10
  searches.zip(raw_results['results']).each do |(target, search_options), result|
11
11
  results_class = if search_options[:class_name]
12
+ Meilisearch::Rails.logger.warn(
13
+ '[meilisearch-rails] The :class_name option in multi search is deprecated, please use :scope instead.'
14
+ )
15
+
12
16
  search_options[:class_name].constantize
13
17
  elsif target.instance_of?(Class)
14
18
  target
19
+ elsif search_options[:scope]
20
+ search_options[:scope]
15
21
  end
16
22
 
17
- @results[target] = results_class ? load_results(results_class, result) : result['hits']
23
+ @results[target] = results_class ? load_results(results_class, result, scope: search_options[:scope]) : result['hits']
18
24
 
19
25
  @metadata[target] = result.except('hits')
20
26
  end
@@ -23,7 +29,7 @@ module MeiliSearch
23
29
  include Enumerable
24
30
 
25
31
  def each_hit(&block)
26
- MeiliSearch::Rails.logger.warn(
32
+ Meilisearch::Rails.logger.warn(
27
33
  <<~DEPRECATION
28
34
  [meilisearch-rails] Flattening multi search results is deprecated.
29
35
  If you do not want the results to be grouped, please use federated search instead.
@@ -36,7 +42,7 @@ module MeiliSearch
36
42
  end
37
43
 
38
44
  def each(&block)
39
- MeiliSearch::Rails.logger.info(
45
+ Meilisearch::Rails.logger.info(
40
46
  <<~INFO
41
47
  [meilisearch-rails] #each on a multi search now iterates through grouped results.
42
48
  If you do not want the results to be grouped, please use federated search instead.
@@ -52,7 +58,7 @@ module MeiliSearch
52
58
  end
53
59
 
54
60
  def to_a
55
- MeiliSearch::Rails.logger.warn(
61
+ Meilisearch::Rails.logger.warn(
56
62
  <<~DEPRECATION
57
63
  [meilisearch-rails] Flattening multi search results is deprecated.
58
64
  If you do not want the results to be grouped, please use federated search instead.
@@ -69,7 +75,9 @@ module MeiliSearch
69
75
 
70
76
  private
71
77
 
72
- def load_results(klass, result)
78
+ def load_results(klass, result, scope:)
79
+ scope ||= klass
80
+
73
81
  pk_method = klass.ms_primary_key_method
74
82
  pk_method = pk_method.in if Utilities.mongo_model?(klass)
75
83
 
@@ -78,7 +86,7 @@ module MeiliSearch
78
86
  hits_by_id =
79
87
  result['hits'].index_by { |hit| hit[condition_key.to_s] }
80
88
 
81
- records = klass.where(condition_key => hits_by_id.keys)
89
+ records = scope.where(condition_key => hits_by_id.keys)
82
90
 
83
91
  if records.respond_to? :in_order_of
84
92
  records.in_order_of(condition_key, hits_by_id.keys).each do |record|
@@ -1,33 +1,72 @@
1
- require_relative 'multi_search/result'
1
+ require_relative 'multi_search/multi_search_result'
2
+ require_relative 'multi_search/federated_search_result'
2
3
 
3
- module MeiliSearch
4
+ module Meilisearch
4
5
  module Rails
5
6
  class << self
6
7
  def multi_search(searches)
7
8
  search_parameters = searches.map do |(index_target, options)|
8
- index_target = options.delete(:index_uid) || index_target
9
+ model_class = options[:scope].respond_to?(:model) ? options[:scope].model : options[:scope]
10
+ index_target = options.delete(:index_uid) || model_class || index_target
9
11
 
10
12
  paginate(options) if pagination_enabled?
11
13
  normalize(options, index_target)
12
14
  end
13
15
 
14
- MultiSearchResult.new(searches, client.multi_search(search_parameters))
16
+ MultiSearchResult.new(searches, client.multi_search(queries: search_parameters))
17
+ end
18
+
19
+ def federated_search(queries:, federation: {})
20
+ if federation.nil?
21
+ Meilisearch::Rails.logger.warn(
22
+ '[meilisearch-rails] In federated_search, `nil` is an invalid `:federation` option. To explicitly use defaults, pass `{}`.'
23
+ )
24
+
25
+ federation = {}
26
+ end
27
+
28
+ queries.map! { |item| [nil, item] } if queries.is_a?(Array)
29
+
30
+ cleaned_queries = queries.filter_map do |(index_target, options)|
31
+ model_class = options[:scope].respond_to?(:model) ? options[:scope].model : options[:scope]
32
+ index_target = options.delete(:index_uid) || index_target || model_class
33
+
34
+ strip_pagination_options(options)
35
+ normalize(options, index_target)
36
+ end
37
+
38
+ raw_results = client.multi_search(queries: cleaned_queries, federation: federation)
39
+
40
+ FederatedSearchResult.new(queries, raw_results)
15
41
  end
16
42
 
17
43
  private
18
44
 
19
45
  def normalize(options, index_target)
46
+ index_target = index_uid_from_target(index_target)
47
+
48
+ return nil if index_target.nil?
49
+
20
50
  options
21
- .except(:class_name)
22
- .merge!(index_uid: index_uid_from_target(index_target))
51
+ .except(:class_name, :scope)
52
+ .merge!(index_uid: index_target)
23
53
  end
24
54
 
25
55
  def index_uid_from_target(index_target)
26
56
  case index_target
27
57
  when String, Symbol
28
58
  index_target
29
- else
30
- index_target.index.uid
59
+ when Class
60
+ if index_target.respond_to?(:index)
61
+ index_target.index.uid
62
+ else
63
+ Meilisearch::Rails.logger.warn <<~MODEL_NOT_INDEXED
64
+ [meilisearch-rails] This class was passed to a multi/federated search but it does not have an #index: #{index_target}
65
+ [meilisearch-rails] Are you sure it has a `meilisearch` block?
66
+ MODEL_NOT_INDEXED
67
+
68
+ nil
69
+ end
31
70
  end
32
71
  end
33
72
 
@@ -43,8 +82,22 @@ module MeiliSearch
43
82
  options[:page] ||= 1
44
83
  end
45
84
 
85
+ def strip_pagination_options(options)
86
+ pagination_options = %w[page hitsPerPage hits_per_page limit offset].select do |key|
87
+ options.delete(key) || options.delete(key.to_sym)
88
+ end
89
+
90
+ return if pagination_options.empty?
91
+
92
+ Meilisearch::Rails.logger.warn <<~WRONG_PAGINATION
93
+ [meilisearch-rails] Pagination options in federated search must apply to whole federation.
94
+ [meilisearch-rails] These options have been removed: #{pagination_options.join(', ')}.
95
+ [meilisearch-rails] Please pass them after queries, in the `federation:` option.
96
+ WRONG_PAGINATION
97
+ end
98
+
46
99
  def pagination_enabled?
47
- MeiliSearch::Rails.configuration[:pagination_backend]
100
+ Meilisearch::Rails.configuration[:pagination_backend]
48
101
  end
49
102
  end
50
103
  end
@@ -1,6 +1,6 @@
1
1
  require 'singleton'
2
2
 
3
- module MeiliSearch
3
+ module Meilisearch
4
4
  module Rails
5
5
  class NullObject
6
6
  include Singleton
@@ -1,11 +1,11 @@
1
1
  unless defined? Kaminari
2
- raise(MeiliSearch::BadConfiguration,
2
+ raise(Meilisearch::BadConfiguration,
3
3
  "Meilisearch: Please add 'kaminari' to your Gemfile to use kaminari pagination backend")
4
4
  end
5
5
 
6
6
  require 'kaminari/models/array_extension'
7
7
 
8
- module MeiliSearch
8
+ module Meilisearch
9
9
  module Rails
10
10
  module Pagination
11
11
  class Kaminari < ::Kaminari::PaginatableArray
@@ -18,7 +18,7 @@ module MeiliSearch
18
18
  end
19
19
 
20
20
  def self.create(results, total_hits, options = {})
21
- unless MeiliSearch::Rails.active?
21
+ unless Meilisearch::Rails.active?
22
22
  total_hits = 0
23
23
  options[:page] = 1
24
24
  options[:per_page] = 1
@@ -1,16 +1,16 @@
1
1
  begin
2
2
  require 'will_paginate/collection'
3
3
  rescue LoadError
4
- raise(MeiliSearch::BadConfiguration,
5
- "MeiliSearch: Please add 'will_paginate' to your Gemfile to use will_paginate pagination backend")
4
+ raise(Meilisearch::BadConfiguration,
5
+ "Meilisearch: Please add 'will_paginate' to your Gemfile to use will_paginate pagination backend")
6
6
  end
7
7
 
8
- module MeiliSearch
8
+ module Meilisearch
9
9
  module Rails
10
10
  module Pagination
11
11
  class WillPaginate
12
12
  def self.create(results, total_hits, options = {})
13
- unless MeiliSearch::Rails.active?
13
+ unless Meilisearch::Rails.active?
14
14
  total_hits = 0
15
15
  options[:page] = 1
16
16
  options[:per_page] = 1
@@ -1,11 +1,11 @@
1
- module MeiliSearch
1
+ module Meilisearch
2
2
  module Rails
3
3
  module Pagination
4
4
  autoload :WillPaginate, 'meilisearch/rails/pagination/will_paginate'
5
5
  autoload :Kaminari, 'meilisearch/rails/pagination/kaminari'
6
6
 
7
7
  def self.create(results, total_hits, options = {})
8
- pagination_backend = MeiliSearch::Rails.configuration[:pagination_backend]
8
+ pagination_backend = Meilisearch::Rails.configuration[:pagination_backend]
9
9
 
10
10
  if pagination_backend.nil? || (is_pagy = pagination_backend.to_s == 'pagy')
11
11
  log_pagy_error if is_pagy
@@ -17,12 +17,12 @@ module MeiliSearch
17
17
  end
18
18
 
19
19
  def self.log_pagy_error
20
- MeiliSearch::Rails.logger
20
+ Meilisearch::Rails.logger
21
21
  .warn('[meilisearch-rails] Remove `pagination_backend: :pagy` from your initializer, `pagy` it is not required for `pagy`')
22
22
  end
23
23
 
24
24
  def self.load_pagination!(pagination_backend, results, total_hits, options)
25
- ::MeiliSearch::Rails::Pagination
25
+ ::Meilisearch::Rails::Pagination
26
26
  .const_get(pagination_backend.to_s.classify)
27
27
  .create(results, total_hits, options)
28
28
  rescue NameError
@@ -1,6 +1,6 @@
1
1
  require 'rails'
2
2
 
3
- module MeiliSearch
3
+ module Meilisearch
4
4
  module Rails
5
5
  class Railtie < ::Rails::Railtie
6
6
  rake_tasks do
@@ -3,21 +3,21 @@ namespace :meilisearch do
3
3
  task reindex: :environment do
4
4
  puts 'Reindexing all Meilisearch models'
5
5
 
6
- MeiliSearch::Rails::Utilities.reindex_all_models
6
+ Meilisearch::Rails::Utilities.reindex_all_models
7
7
  end
8
8
 
9
9
  desc 'Set settings to all indexes'
10
10
  task set_all_settings: :environment do
11
11
  puts 'Set settings in all Meilisearch models'
12
12
 
13
- MeiliSearch::Rails::Utilities.set_settings_all_models
13
+ Meilisearch::Rails::Utilities.set_settings_all_models
14
14
  end
15
15
 
16
16
  desc 'Clear all indexes'
17
17
  task clear_indexes: :environment do
18
18
  puts 'Clearing indexes from all Meilisearch models'
19
19
 
20
- MeiliSearch::Rails::Utilities.clear_all_indexes
20
+ Meilisearch::Rails::Utilities.clear_all_indexes
21
21
  end
22
22
 
23
23
  desc 'Create initializer file'
@@ -1,4 +1,4 @@
1
- MeiliSearch::Rails.configuration = {
1
+ Meilisearch::Rails.configuration = {
2
2
  meilisearch_url: ENV.fetch('MEILISEARCH_HOST', 'http://localhost:7700'),
3
3
  meilisearch_api_key: ENV.fetch('MEILISEARCH_API_KEY', 'YourMeilisearchAPIKey')
4
4
  }
@@ -1,4 +1,4 @@
1
- module MeiliSearch
1
+ module Meilisearch
2
2
  module Rails
3
3
  module Utilities
4
4
  class << self
@@ -8,7 +8,7 @@ module MeiliSearch
8
8
  elsif ::Rails.application
9
9
  ::Rails.application.eager_load!
10
10
  end
11
- klasses = MeiliSearch::Rails.instance_variable_get(:@included_in)
11
+ klasses = Meilisearch::Rails.instance_variable_get(:@included_in)
12
12
  (klasses + klasses.map(&:descendants).flatten).uniq
13
13
  end
14
14
 
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module MeiliSearch
3
+ module Meilisearch
4
4
  module Rails
5
- VERSION = '0.14.3'
5
+ VERSION = '0.15.0'
6
6
 
7
7
  def self.qualified_version
8
8
  "Meilisearch Rails (v#{VERSION})"
@@ -20,7 +20,13 @@ end
20
20
 
21
21
  require 'logger'
22
22
 
23
- module MeiliSearch
23
+ # Workaround for the soft deprecation of MeiliSearch (old spelling)
24
+ # The regular `const_get` method does not seem to work
25
+ # too well with autoload and thus does not pull in methods
26
+ # like `client` which are obviously vital.
27
+ MeiliSearch::Rails = Meilisearch::Rails
28
+
29
+ module Meilisearch
24
30
  module Rails
25
31
  autoload :Configuration, 'meilisearch/rails/configuration'
26
32
  extend Configuration
@@ -97,7 +103,7 @@ module MeiliSearch
97
103
  [meilisearch-rails] #{missing_searchable} declared in searchable_attributes but not in attributes. \
98
104
  Please add it to attributes if it should be searchable.
99
105
  WARNING
100
- MeiliSearch::Rails.logger.warn(warning)
106
+ Meilisearch::Rails.logger.warn(warning)
101
107
  end
102
108
  end
103
109
  end
@@ -270,12 +276,12 @@ module MeiliSearch
270
276
  autoload :MSCleanUpJob, 'meilisearch/rails/ms_clean_up_job'
271
277
  end
272
278
 
273
- # this class wraps an MeiliSearch::Index document ensuring all raised exceptions
279
+ # this class wraps an Meilisearch::Index document ensuring all raised exceptions
274
280
  # are correctly logged or thrown depending on the `raise_on_failure` option
275
281
  class SafeIndex
276
282
  def initialize(index_uid, raise_on_failure, options)
277
- client = MeiliSearch::Rails.client
278
- primary_key = options[:primary_key] || MeiliSearch::Rails::IndexSettings::DEFAULT_PRIMARY_KEY
283
+ client = Meilisearch::Rails.client
284
+ primary_key = options[:primary_key] || Meilisearch::Rails::IndexSettings::DEFAULT_PRIMARY_KEY
279
285
  @raise_on_failure = raise_on_failure.nil? || raise_on_failure
280
286
 
281
287
  SafeIndex.log_or_throw(nil, @raise_on_failure) do
@@ -285,7 +291,7 @@ module MeiliSearch
285
291
  @index = client.index(index_uid)
286
292
  end
287
293
 
288
- ::MeiliSearch::Index.instance_methods(false).each do |m|
294
+ ::Meilisearch::Index.instance_methods(false).each do |m|
289
295
  define_method(m) do |*args, &block|
290
296
  if m == :update_settings
291
297
  args[0].delete(:attributes_to_highlight) if args[0][:attributes_to_highlight]
@@ -294,7 +300,7 @@ module MeiliSearch
294
300
  end
295
301
 
296
302
  SafeIndex.log_or_throw(m, @raise_on_failure) do
297
- return MeiliSearch::Rails.black_hole unless MeiliSearch::Rails.active?
303
+ return Meilisearch::Rails.black_hole unless Meilisearch::Rails.active?
298
304
 
299
305
  @index.send(m, *args, &block)
300
306
  end
@@ -304,7 +310,7 @@ module MeiliSearch
304
310
  # Maually define facet_search due to complications with **opts in ruby 2.*
305
311
  def facet_search(*args, **opts)
306
312
  SafeIndex.log_or_throw(:facet_search, @raise_on_failure) do
307
- return MeiliSearch::Rails.black_hole unless MeiliSearch::Rails.active?
313
+ return Meilisearch::Rails.black_hole unless Meilisearch::Rails.active?
308
314
 
309
315
  @index.facet_search(*args, **opts)
310
316
  end
@@ -323,7 +329,7 @@ module MeiliSearch
323
329
  def settings(*args)
324
330
  SafeIndex.log_or_throw(:settings, @raise_on_failure) do
325
331
  @index.settings(*args)
326
- rescue ::MeiliSearch::ApiError => e
332
+ rescue ::Meilisearch::ApiError => e
327
333
  return {} if e.code == 'index_not_found' # not fatal
328
334
 
329
335
  raise e
@@ -332,11 +338,11 @@ module MeiliSearch
332
338
 
333
339
  def self.log_or_throw(method, raise_on_failure, &block)
334
340
  yield
335
- rescue ::MeiliSearch::TimeoutError, ::MeiliSearch::ApiError => e
341
+ rescue ::Meilisearch::TimeoutError, ::Meilisearch::ApiError => e
336
342
  raise e if raise_on_failure
337
343
 
338
344
  # log the error
339
- MeiliSearch::Rails.logger.info("[meilisearch-rails] #{e.message}")
345
+ Meilisearch::Rails.logger.info("[meilisearch-rails] #{e.message}")
340
346
  # return something
341
347
  case method.to_s
342
348
  when 'search'
@@ -349,7 +355,7 @@ module MeiliSearch
349
355
  end
350
356
  end
351
357
 
352
- # these are the class methods added when MeiliSearch is included
358
+ # these are the class methods added when Meilisearch is included
353
359
  module ClassMethods
354
360
  def self.extended(base)
355
361
  class << base
@@ -379,7 +385,7 @@ module MeiliSearch
379
385
  attr_accessor :formatted
380
386
 
381
387
  if options.key?(:per_environment)
382
- raise BadConfiguration, ':per_environment option should be defined globally on MeiliSearch::Rails.configuration block.'
388
+ raise BadConfiguration, ':per_environment option should be defined globally on Meilisearch::Rails.configuration block.'
383
389
  end
384
390
 
385
391
  if options[:synchronous] == true
@@ -415,7 +421,7 @@ module MeiliSearch
415
421
  raise ArgumentError, "Invalid `enqueue` option: #{options[:enqueue]}"
416
422
  end
417
423
  meilisearch_options[:enqueue] = proc do |record, remove|
418
- proc.call(record, remove) if ::MeiliSearch::Rails.active? && !ms_without_auto_index_scope
424
+ proc.call(record, remove) if ::Meilisearch::Rails.active? && !ms_without_auto_index_scope
419
425
  end
420
426
  end
421
427
  unless options[:auto_index] == false
@@ -499,7 +505,7 @@ module MeiliSearch
499
505
  Thread.current["ms_without_auto_index_scope_for_#{model_name}"]
500
506
  end
501
507
 
502
- def ms_reindex!(batch_size = MeiliSearch::Rails::IndexSettings::DEFAULT_BATCH_SIZE, synchronous = false)
508
+ def ms_reindex!(batch_size = Meilisearch::Rails::IndexSettings::DEFAULT_BATCH_SIZE, synchronous = false)
503
509
  return if ms_without_auto_index_scope
504
510
 
505
511
  ms_configurations.each do |options, settings|
@@ -622,7 +628,7 @@ module MeiliSearch
622
628
 
623
629
  index = ms_ensure_init(options, settings)
624
630
  synchronous || options[:synchronous] ? index.delete_all_documents.await : index.delete_all_documents
625
- @ms_indexes[MeiliSearch::Rails.active?][settings] = nil
631
+ @ms_indexes[Meilisearch::Rails.active?][settings] = nil
626
632
  end
627
633
  nil
628
634
  end
@@ -666,7 +672,7 @@ module MeiliSearch
666
672
  end
667
673
 
668
674
  def ms_search(query, params = {})
669
- if MeiliSearch::Rails.configuration[:pagination_backend]
675
+ if Meilisearch::Rails.configuration[:pagination_backend]
670
676
  %i[page hitsPerPage hits_per_page].each do |key|
671
677
  params[key.to_s.underscore.to_sym] = params[key].to_i if params.key?(key)
672
678
  end
@@ -736,7 +742,7 @@ module MeiliSearch
736
742
 
737
743
  def ms_index_uid(options = nil)
738
744
  options ||= meilisearch_options
739
- global_options ||= MeiliSearch::Rails.configuration
745
+ global_options ||= Meilisearch::Rails.configuration
740
746
 
741
747
  name = options[:index_uid] || model_name.to_s.gsub('::', '_')
742
748
  name = "#{name}_#{::Rails.env}" if global_options[:per_environment]
@@ -788,11 +794,11 @@ module MeiliSearch
788
794
 
789
795
  @ms_indexes ||= { true => {}, false => {} }
790
796
 
791
- @ms_indexes[MeiliSearch::Rails.active?][settings] ||= SafeIndex.new(ms_index_uid(options), meilisearch_options[:raise_on_failure], meilisearch_options)
797
+ @ms_indexes[Meilisearch::Rails.active?][settings] ||= SafeIndex.new(ms_index_uid(options), meilisearch_options[:raise_on_failure], meilisearch_options)
792
798
 
793
- update_settings_if_changed(@ms_indexes[MeiliSearch::Rails.active?][settings], options, user_configuration)
799
+ update_settings_if_changed(@ms_indexes[Meilisearch::Rails.active?][settings], options, user_configuration)
794
800
 
795
- @ms_indexes[MeiliSearch::Rails.active?][settings]
801
+ @ms_indexes[Meilisearch::Rails.active?][settings]
796
802
  end
797
803
 
798
804
  private
@@ -845,7 +851,7 @@ module MeiliSearch
845
851
  end
846
852
 
847
853
  def ms_pk(options = nil)
848
- options[:primary_key] || MeiliSearch::Rails::IndexSettings::DEFAULT_PRIMARY_KEY
854
+ options[:primary_key] || Meilisearch::Rails::IndexSettings::DEFAULT_PRIMARY_KEY
849
855
  end
850
856
 
851
857
  def meilisearch_settings_changed?(server_state, user_configuration)
@@ -5,7 +5,7 @@ require 'meilisearch/rails/version'
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = 'meilisearch-rails'
8
- s.version = MeiliSearch::Rails::VERSION
8
+ s.version = Meilisearch::Rails::VERSION
9
9
 
10
10
  s.authors = ['Meili']
11
11
  s.email = 'bonjour@meilisearch.com'
@@ -34,6 +34,6 @@ Gem::Specification.new do |s|
34
34
 
35
35
  s.required_ruby_version = '>= 3.0.0'
36
36
 
37
- s.add_dependency 'meilisearch', '~> 0.28.4'
37
+ s.add_dependency 'meilisearch', '~> 0.31.0'
38
38
  s.add_dependency 'mutex_m', '~> 0.2'
39
39
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: meilisearch-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.3
4
+ version: 0.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Meili
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-03-13 00:00:00.000000000 Z
11
+ date: 2025-03-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: meilisearch
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.28.4
19
+ version: 0.31.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.28.4
26
+ version: 0.31.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: mutex_m
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -57,7 +57,8 @@ files:
57
57
  - lib/meilisearch/rails/ms_clean_up_job.rb
58
58
  - lib/meilisearch/rails/ms_job.rb
59
59
  - lib/meilisearch/rails/multi_search.rb
60
- - lib/meilisearch/rails/multi_search/result.rb
60
+ - lib/meilisearch/rails/multi_search/federated_search_result.rb
61
+ - lib/meilisearch/rails/multi_search/multi_search_result.rb
61
62
  - lib/meilisearch/rails/null_object.rb
62
63
  - lib/meilisearch/rails/pagination.rb
63
64
  - lib/meilisearch/rails/pagination/kaminari.rb