meilisearch-rails 0.10.2 → 0.14.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cb990c26e799658b655df059ea7a22b4cfc7511a88e7581d72c27841b736f74f
4
- data.tar.gz: c2457a258356732877729a9f110a8f392316a98d725d6d052f2dc64824a3ea2f
3
+ metadata.gz: 24559c8e70fcdaef7392de52e689ed37427c1e87a8981e693f123c8b7348d75a
4
+ data.tar.gz: 415f7739643c82925fa54dc3b6a3d2dcf182d66969010fc84d3cf64a9444fc37
5
5
  SHA512:
6
- metadata.gz: 7499509091a149069f1322e3ceec9c789432c3495d8c2754d258bb17c5cc1d70a410ebcd41e1eb76bcbe50b3c9e301044d0a5e6931e94bdd8779eb290e9eaecf
7
- data.tar.gz: 68173b7d7767308144b6987c35c9c2fb75806959a6fcdc3ee3545cab88779d24e013dea0ea0b3b0a3182f8fb9bcd5c7e1634aaf89ecd39f4cb7ad21231b95a0b
6
+ metadata.gz: ce2015617e15a63f5d9fa39686b92272e83fb70c8ae66144847aa712ac51341ff1f56073006936fb568996105ee45142cedccfb5123befd79a033312efd37173
7
+ data.tar.gz: a906f6cc4bb10f6de8c38e19ab4225ffc7a1009517dedf0849972af3a6df50d6518371e66660477a8eb92291266bfea23e5ae135ebc3ca6f611e9e17828a4429
data/.rspec CHANGED
@@ -1 +1,2 @@
1
1
  --color
2
+ --require spec_helper
data/Gemfile CHANGED
@@ -31,7 +31,7 @@ group :test do
31
31
  gem 'jdbc-sqlite3', platform: :jruby
32
32
  gem 'rspec', '~> 3.0'
33
33
  gem 'simplecov', require: 'false'
34
- gem 'codecov', require: 'false'
34
+ gem 'simplecov-cobertura', require: 'false'
35
35
  gem 'threads'
36
36
 
37
37
  gem 'byebug'
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2021-2022 Meili SAS
3
+ Copyright (c) 2021-2024 Meili SAS
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -38,6 +38,7 @@
38
38
  - [Compatibility](#-compatibility)
39
39
  - [⚙️ Settings](#️-settings)
40
40
  - [🔍 Custom search](#-custom-search)
41
+ - [🔍🔍 Multi search](#-multi-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-)
@@ -75,7 +76,7 @@ This package guarantees compatibility with [version v1.x of Meilisearch](https:/
75
76
 
76
77
  ## 🔧 Installation <!-- omit in toc -->
77
78
 
78
- This package requires Ruby version 2.7.0 or later and Rails 6.1 or later. It may work in older versions but it is not officially supported.
79
+ This package requires Ruby version 3.0 or later and Rails 6.1 or later. It may work in older versions but it is not officially supported.
79
80
 
80
81
  With `gem` in command line:
81
82
  ```bash
@@ -206,6 +207,7 @@ class Book < ApplicationRecord
206
207
  crop_length 10
207
208
  faceting max_values_per_facet: 2000
208
209
  pagination max_total_hits: 1000
210
+ proximity_precision 'byWord'
209
211
  end
210
212
  end
211
213
  ```
@@ -229,7 +231,7 @@ harry_book.formatted # => {"id"=>"1", "name"=>"<em>Harry</em> Potter", "descript
229
231
  👉 Don't forget that `attributes_to_highlight`, `attributes_to_crop`, and
230
232
  `crop_length` can be set up in the `meilisearch` block of your model.
231
233
 
232
- ## 🔍 Sorted search
234
+ ### 🔍 Sorted search
233
235
 
234
236
  As an example of how to use the sort option, here is how you could achieve
235
237
  returning all books sorted by title in ascending order:
@@ -240,6 +242,58 @@ Book.search('*', sort: ['title:asc'])
240
242
 
241
243
  👉 Don't forget to set up the `sortable_attributes` option in the `meilisearch` block of your model.
242
244
 
245
+ ## 🔍🔍 Multi search
246
+
247
+ Meilisearch supports searching multiple models at the same time (see [🔍 Custom search](#-custom-search) for search options):
248
+
249
+ ```ruby
250
+ multi_search_results = MeiliSearch::Rails.multi_search(
251
+ Book => { q: 'Harry' },
252
+ Manga => { q: 'Attack' }
253
+ )
254
+ ```
255
+
256
+ You can iterate through the results with `.each` or `.each_result`:
257
+
258
+ ```erb
259
+ <% multi_search_results.each do |record| %>
260
+ <p><%= record.title %></p>
261
+ <p><%= record.author %></p>
262
+ <% end %>
263
+
264
+ <p>Harry Potter and the Philosopher's Stone</p>
265
+ <p>J. K. Rowling</p>
266
+ <p>Harry Potter and the Chamber of Secrets</p>
267
+ <p>J. K. Rowling</p>
268
+ <p>Attack on Titan</p>
269
+ <p>Iseyama</p>
270
+ ```
271
+
272
+ ```erb
273
+ <% multi_search_results.each_result do |klass, results| %>
274
+ <p><%= klass.name.pluralize %></p>
275
+
276
+ <ul>
277
+ <% results.each do |record| %>
278
+ <li><%= record.title %></li>
279
+ <% end %>
280
+ </ul>
281
+ <% end %>
282
+
283
+
284
+ <p>Books</p>
285
+ <ul>
286
+ <li>Harry Potter and the Philosopher's Stone</li>
287
+ <li>Harry Potter and the Chamber of Secrets</li>
288
+ </ul>
289
+ <p>Mangas</p>
290
+ <ul>
291
+ <li>Attack on Titan</li>
292
+ </ul>
293
+ ```
294
+
295
+ See the [official multi search documentation](https://www.meilisearch.com/docs/reference/api/multi_search).
296
+
243
297
  ## 🪛 Options
244
298
 
245
299
  ### Meilisearch configuration & environment
@@ -0,0 +1,19 @@
1
+ module MeiliSearch
2
+ module Rails
3
+ class MSCleanUpJob < ::ActiveJob::Base
4
+ queue_as :meilisearch
5
+
6
+ def perform(documents)
7
+ documents.each do |document|
8
+ index = MeiliSearch::Rails.client.index(document[:index_uid])
9
+
10
+ if document[:synchronous]
11
+ index.delete_document(document[:primary_key]).await
12
+ else
13
+ index.delete_document(document[:primary_key])
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,84 @@
1
+ module MeiliSearch
2
+ module Rails
3
+ class MultiSearchResult
4
+ attr_reader :metadata
5
+
6
+ def initialize(searches, raw_results)
7
+ @results = {}
8
+ @metadata = {}
9
+
10
+ searches.zip(raw_results['results']).each do |(index_target, search_options), result|
11
+ index_target = search_options[:class_name].constantize if search_options[:class_name]
12
+
13
+ @results[index_target] = case index_target
14
+ when String, Symbol
15
+ result['hits']
16
+ else
17
+ load_results(index_target, result)
18
+ end
19
+
20
+ @metadata[index_target] = result.except('hits')
21
+ end
22
+ end
23
+
24
+ include Enumerable
25
+
26
+ def each_hit(&block)
27
+ @results.each do |_index_target, results|
28
+ results.each(&block)
29
+ end
30
+ end
31
+ alias each each_hit
32
+
33
+ def each_result(&block)
34
+ @results.each(&block)
35
+ end
36
+
37
+ def to_a
38
+ @results.values.flatten(1)
39
+ end
40
+ alias to_ary to_a
41
+
42
+ def to_h
43
+ @results
44
+ end
45
+ alias to_hash to_h
46
+
47
+ private
48
+
49
+ def load_results(klass, result)
50
+ pk_method = klass.ms_primary_key_method
51
+ pk_method = pk_method.in if Utilities.mongo_model?(klass)
52
+
53
+ condition_key = pk_is_virtual?(klass, pk_method) ? klass.primary_key : pk_method
54
+
55
+ hits_by_id =
56
+ result['hits'].index_by { |hit| hit[condition_key.to_s] }
57
+
58
+ records = klass.where(condition_key => hits_by_id.keys)
59
+
60
+ if records.respond_to? :in_order_of
61
+ records.in_order_of(condition_key, hits_by_id.keys).each do |record|
62
+ record.formatted = hits_by_id[record.send(condition_key).to_s]['_formatted']
63
+ end
64
+ else
65
+ results_by_id = records.index_by do |hit|
66
+ hit.send(condition_key).to_s
67
+ end
68
+
69
+ result['hits'].filter_map do |hit|
70
+ record = results_by_id[hit[condition_key.to_s].to_s]
71
+ record&.formatted = hit['_formatted']
72
+ record
73
+ end
74
+ end
75
+ end
76
+
77
+ def pk_is_virtual?(model_class, pk_method)
78
+ model_class.columns
79
+ .map(&(Utilities.sequel_model?(model_class) ? :to_s : :name))
80
+ .exclude?(pk_method.to_s)
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,49 @@
1
+ require_relative 'multi_search/result'
2
+
3
+ module MeiliSearch
4
+ module Rails
5
+ class << self
6
+ def multi_search(searches)
7
+ search_parameters = searches.map do |(index_target, options)|
8
+ paginate(options) if pagination_enabled?
9
+ normalize(options, index_target)
10
+ end
11
+
12
+ MultiSearchResult.new(searches, client.multi_search(search_parameters))
13
+ end
14
+
15
+ private
16
+
17
+ def normalize(options, index_target)
18
+ options
19
+ .except(:class_name)
20
+ .merge!(index_uid: index_uid_from_target(index_target))
21
+ end
22
+
23
+ def index_uid_from_target(index_target)
24
+ case index_target
25
+ when String, Symbol
26
+ index_target
27
+ else
28
+ index_target.index.uid
29
+ end
30
+ end
31
+
32
+ def paginate(options)
33
+ %w[page hitsPerPage hits_per_page].each do |key|
34
+ # Deletes hitsPerPage to avoid passing along a meilisearch-ruby warning/exception
35
+ value = options.delete(key) || options.delete(key.to_sym)
36
+ options[key.underscore.to_sym] = value.to_i if value
37
+ end
38
+
39
+ # It is required to activate the finite pagination in Meilisearch v0.30 (or newer),
40
+ # to have at least `hits_per_page` defined or `page` in the search request.
41
+ options[:page] ||= 1
42
+ end
43
+
44
+ def pagination_enabled?
45
+ MeiliSearch::Rails.configuration[:pagination_backend]
46
+ end
47
+ end
48
+ end
49
+ end
@@ -18,7 +18,7 @@ module MeiliSearch
18
18
 
19
19
  def self.log_pagy_error
20
20
  MeiliSearch::Rails.logger
21
- .warning('[meilisearch-rails] Remove `pagination_backend: :pagy` from your initializer, `pagy` it is not required for `pagy`')
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)
@@ -48,6 +48,14 @@ module MeiliSearch
48
48
  true
49
49
  end
50
50
 
51
+ def mongo_model?(model_class)
52
+ defined?(::Mongoid::Document) && model_class.include?(::Mongoid::Document)
53
+ end
54
+
55
+ def sequel_model?(model_class)
56
+ defined?(::Sequel::Model) && model_class < Sequel::Model
57
+ end
58
+
51
59
  private
52
60
 
53
61
  def constraint_passes?(record, constraint)
@@ -2,7 +2,7 @@
2
2
 
3
3
  module MeiliSearch
4
4
  module Rails
5
- VERSION = '0.10.2'
5
+ VERSION = '0.14.1'
6
6
 
7
7
  def self.qualified_version
8
8
  "Meilisearch Rails (v#{VERSION})"
@@ -3,6 +3,7 @@ require 'meilisearch/rails/null_object'
3
3
  require 'meilisearch/rails/version'
4
4
  require 'meilisearch/rails/utilities'
5
5
  require 'meilisearch/rails/errors'
6
+ require 'meilisearch/rails/multi_search'
6
7
 
7
8
  if defined? Rails
8
9
  begin
@@ -66,6 +67,7 @@ module MeiliSearch
66
67
  pagination
67
68
  faceting
68
69
  typo_tolerance
70
+ proximity_precision
69
71
  ].freeze
70
72
 
71
73
  CAMELIZE_OPTIONS = %i[pagination faceting typo_tolerance].freeze
@@ -82,6 +84,22 @@ module MeiliSearch
82
84
  def initialize(options, &block)
83
85
  @options = options
84
86
  instance_exec(&block) if block_given?
87
+ warn_searchable_missing_attributes
88
+ end
89
+
90
+ def warn_searchable_missing_attributes
91
+ searchables = get_setting(:searchable_attributes)&.map { |searchable| searchable.to_s.split('.').first }
92
+ attrs = get_setting(:attributes)&.map { |k, _| k.to_s }
93
+
94
+ if searchables.present? && attrs.present?
95
+ (searchables - attrs).each do |missing_searchable|
96
+ warning = <<~WARNING
97
+ [meilisearch-rails] #{missing_searchable} declared in searchable_attributes but not in attributes. \
98
+ Please add it to attributes if it should be searchable.
99
+ WARNING
100
+ MeiliSearch::Rails.logger.warn(warning)
101
+ end
102
+ end
85
103
  end
86
104
 
87
105
  def use_serializer(serializer)
@@ -249,6 +267,7 @@ module MeiliSearch
249
267
  # lazy load the ActiveJob class to ensure the
250
268
  # queue is initialized before using it
251
269
  autoload :MSJob, 'meilisearch/rails/ms_job'
270
+ autoload :MSCleanUpJob, 'meilisearch/rails/ms_clean_up_job'
252
271
  end
253
272
 
254
273
  # this class wraps an MeiliSearch::Index document ensuring all raised exceptions
@@ -282,6 +301,15 @@ module MeiliSearch
282
301
  end
283
302
  end
284
303
 
304
+ # Maually define facet_search due to complications with **opts in ruby 2.*
305
+ def facet_search(*args, **opts)
306
+ SafeIndex.log_or_throw(:facet_search, @raise_on_failure) do
307
+ return MeiliSearch::Rails.black_hole unless MeiliSearch::Rails.active?
308
+
309
+ @index.facet_search(*args, **opts)
310
+ end
311
+ end
312
+
285
313
  # special handling of wait_for_task to handle null task_id
286
314
  def wait_for_task(task_uid)
287
315
  return if task_uid.nil? && !@raise_on_failure # ok
@@ -296,7 +324,7 @@ module MeiliSearch
296
324
  SafeIndex.log_or_throw(:settings, @raise_on_failure) do
297
325
  @index.settings(*args)
298
326
  rescue ::MeiliSearch::ApiError => e
299
- return {} if e.code == 404 # not fatal
327
+ return {} if e.code == 'index_not_found' # not fatal
300
328
 
301
329
  raise e
302
330
  end
@@ -373,7 +401,11 @@ module MeiliSearch
373
401
 
374
402
  proc = if options[:enqueue] == true
375
403
  proc do |record, remove|
376
- MSJob.perform_later(record, remove ? 'ms_remove_from_index!' : 'ms_index!')
404
+ if remove
405
+ MSCleanUpJob.perform_later(record.ms_entries)
406
+ else
407
+ MSJob.perform_later(record, 'ms_index!')
408
+ end
377
409
  end
378
410
  elsif options[:enqueue].respond_to?(:call)
379
411
  options[:enqueue]
@@ -445,11 +477,9 @@ module MeiliSearch
445
477
  end
446
478
  end
447
479
  elsif respond_to?(:after_destroy)
448
- after_destroy { |searchable| searchable.ms_enqueue_remove_from_index!(ms_synchronous?) }
480
+ after_destroy_commit { |searchable| searchable.ms_enqueue_remove_from_index!(ms_synchronous?) }
449
481
  end
450
482
  end
451
-
452
- warn_searchable_missing_attributes
453
483
  end
454
484
 
455
485
  def ms_without_auto_index(&block)
@@ -526,7 +556,8 @@ module MeiliSearch
526
556
  def ms_index!(document, synchronous = false)
527
557
  return if ms_without_auto_index_scope
528
558
 
529
- ms_configurations.each do |options, settings|
559
+ # MS tasks to be returned
560
+ ms_configurations.map do |options, settings|
530
561
  next if ms_indexing_disabled?(options)
531
562
 
532
563
  primary_key = ms_primary_key_of(document, options)
@@ -538,20 +569,32 @@ module MeiliSearch
538
569
  doc = doc.merge ms_pk(options) => primary_key
539
570
 
540
571
  if synchronous || options[:synchronous]
541
- index.add_documents!(doc)
572
+ index.add_documents(doc).await
542
573
  else
543
574
  index.add_documents(doc)
544
575
  end
545
576
  elsif ms_conditional_index?(options) && primary_key.present?
546
577
  # remove non-indexable documents
547
578
  if synchronous || options[:synchronous]
548
- index.delete_document!(primary_key)
579
+ index.delete_document(primary_key).await
549
580
  else
550
581
  index.delete_document(primary_key)
551
582
  end
552
583
  end
584
+ end.compact
585
+ end
586
+
587
+ def ms_entries_for(document:, synchronous:)
588
+ primary_key = ms_primary_key_of(document)
589
+ raise ArgumentError, 'Cannot index a record without a primary key' if primary_key.blank?
590
+
591
+ ms_configurations.filter_map do |options, settings|
592
+ {
593
+ synchronous: synchronous || options[:synchronous],
594
+ index_uid: ms_index_uid(options),
595
+ primary_key: primary_key
596
+ }.with_indifferent_access unless ms_indexing_disabled?(options)
553
597
  end
554
- nil
555
598
  end
556
599
 
557
600
  def ms_remove_from_index!(document, synchronous = false)
@@ -565,7 +608,7 @@ module MeiliSearch
565
608
 
566
609
  index = ms_ensure_init(options, settings)
567
610
  if synchronous || options[:synchronous]
568
- index.delete_document!(primary_key)
611
+ index.delete_document(primary_key).await
569
612
  else
570
613
  index.delete_document(primary_key)
571
614
  end
@@ -578,7 +621,7 @@ module MeiliSearch
578
621
  next if ms_indexing_disabled?(options)
579
622
 
580
623
  index = ms_ensure_init(options, settings)
581
- synchronous || options[:synchronous] ? index.delete_all_documents! : index.delete_all_documents
624
+ synchronous || options[:synchronous] ? index.delete_all_documents.await : index.delete_all_documents
582
625
  @ms_indexes[MeiliSearch::Rails.active?][settings] = nil
583
626
  end
584
627
  nil
@@ -733,35 +776,45 @@ module MeiliSearch
733
776
  false
734
777
  end
735
778
 
779
+ def ms_primary_key_method(options = nil)
780
+ options ||= meilisearch_options
781
+ options[:primary_key] || options[:id] || :id
782
+ end
783
+
736
784
  protected
737
785
 
738
- def ms_ensure_init(options = nil, settings = nil, index_settings = nil)
786
+ def ms_ensure_init(options = meilisearch_options, settings = meilisearch_settings, user_configuration = settings.to_settings)
739
787
  raise ArgumentError, 'No `meilisearch` block found in your model.' if meilisearch_settings.nil?
740
788
 
741
789
  @ms_indexes ||= { true => {}, false => {} }
742
790
 
743
- options ||= meilisearch_options
744
- settings ||= meilisearch_settings
791
+ @ms_indexes[MeiliSearch::Rails.active?][settings] ||= SafeIndex.new(ms_index_uid(options), meilisearch_options[:raise_on_failure], meilisearch_options)
745
792
 
746
- return @ms_indexes[MeiliSearch::Rails.active?][settings] if @ms_indexes[MeiliSearch::Rails.active?][settings]
793
+ update_settings_if_changed(@ms_indexes[MeiliSearch::Rails.active?][settings], options, user_configuration)
747
794
 
748
- @ms_indexes[MeiliSearch::Rails.active?][settings] = SafeIndex.new(ms_index_uid(options), meilisearch_options[:raise_on_failure], meilisearch_options)
795
+ @ms_indexes[MeiliSearch::Rails.active?][settings]
796
+ end
749
797
 
750
- current_settings = @ms_indexes[MeiliSearch::Rails.active?][settings].settings(getVersion: 1) rescue nil # if the index doesn't exist
798
+ private
751
799
 
752
- index_settings ||= settings.to_settings
753
- index_settings = options[:primary_settings].to_settings.merge(index_settings) if options[:inherit]
800
+ def update_settings_if_changed(index, options, user_configuration)
801
+ server_state = index.settings
802
+ user_configuration = options[:primary_settings].to_settings.merge(user_configuration) if options[:inherit]
754
803
 
755
- options[:check_settings] = true if options[:check_settings].nil?
804
+ config = user_configuration.except(:attributes_to_highlight, :attributes_to_crop, :crop_length)
756
805
 
757
- if !ms_indexing_disabled?(options) && options[:check_settings] && meilisearch_settings_changed?(current_settings, index_settings)
758
- @ms_indexes[MeiliSearch::Rails.active?][settings].update_settings(index_settings)
806
+ if !skip_checking_settings?(options) && meilisearch_settings_changed?(server_state, config)
807
+ index.update_settings(user_configuration)
759
808
  end
809
+ end
760
810
 
761
- @ms_indexes[MeiliSearch::Rails.active?][settings]
811
+ def skip_checking_settings?(options)
812
+ ms_indexing_disabled?(options) || ms_checking_disabled?(options)
762
813
  end
763
814
 
764
- private
815
+ def ms_checking_disabled?(options)
816
+ options[:check_settings] == false
817
+ end
765
818
 
766
819
  def ms_configurations
767
820
  raise ArgumentError, 'No `meilisearch` block found in your model.' if meilisearch_settings.nil?
@@ -782,11 +835,6 @@ module MeiliSearch
782
835
  @configurations
783
836
  end
784
837
 
785
- def ms_primary_key_method(options = nil)
786
- options ||= meilisearch_options
787
- options[:primary_key] || options[:id] || :id
788
- end
789
-
790
838
  def ms_primary_key_of(doc, options = nil)
791
839
  doc.send(ms_primary_key_method(options)).to_s
792
840
  end
@@ -800,19 +848,22 @@ module MeiliSearch
800
848
  options[:primary_key] || MeiliSearch::Rails::IndexSettings::DEFAULT_PRIMARY_KEY
801
849
  end
802
850
 
803
- def meilisearch_settings_changed?(prev, current)
804
- return true if prev.nil?
851
+ def meilisearch_settings_changed?(server_state, user_configuration)
852
+ return true if server_state.nil?
805
853
 
806
- current.each do |k, v|
807
- prev_v = prev[k.to_s]
808
- if v.is_a?(Array) && prev_v.is_a?(Array)
809
- # compare array of strings, avoiding symbols VS strings comparison
810
- return true if v.map(&:to_s) != prev_v.map(&:to_s)
811
- elsif prev_v != v
812
- return true
854
+ user_configuration.transform_keys! { |key| key.to_s.camelize(:lower) }
855
+
856
+ user_configuration.any? do |key, user|
857
+ server = server_state[key]
858
+
859
+ if user.is_a?(Hash) && server.is_a?(Hash)
860
+ meilisearch_settings_changed?(server, user)
861
+ elsif user.is_a?(Array) && server.is_a?(Array)
862
+ user.map(&:to_s).sort! != server.map(&:to_s).sort!
863
+ else
864
+ user.to_s != server.to_s
813
865
  end
814
866
  end
815
- false
816
867
  end
817
868
 
818
869
  def ms_conditional_index?(options = nil)
@@ -864,19 +915,6 @@ module MeiliSearch
864
915
  # We don't know if the attribute has changed, so conservatively assume it has
865
916
  true
866
917
  end
867
-
868
- def warn_searchable_missing_attributes
869
- searchables = meilisearch_settings.get_setting(:searchable_attributes)
870
- attrs = meilisearch_settings.get_setting(:attributes)&.keys
871
-
872
- if searchables.present? && attrs.present?
873
- (searchables.map(&:to_s) - attrs.map(&:to_s)).each do |missing_searchable|
874
- MeiliSearch::Rails.logger.warn(
875
- "[meilisearch-rails] #{name}##{missing_searchable} declared in searchable_attributes but not in attributes. Please add it to attributes if it should be searchable."
876
- )
877
- end
878
- end
879
- end
880
918
  end
881
919
 
882
920
  # these are the instance methods included
@@ -923,6 +961,10 @@ module MeiliSearch
923
961
  @ms_synchronous
924
962
  end
925
963
 
964
+ def ms_entries(synchronous = false)
965
+ self.class.ms_entries_for(document: self, synchronous: synchronous || ms_synchronous?)
966
+ end
967
+
926
968
  private
927
969
 
928
970
  def ms_mark_synchronous
@@ -32,7 +32,7 @@ Gem::Specification.new do |s|
32
32
  'Rakefile'
33
33
  ]
34
34
 
35
- s.required_ruby_version = '>= 2.6.0'
35
+ s.required_ruby_version = '>= 3.0.0'
36
36
 
37
- s.add_dependency 'meilisearch', '~> 0.26.0'
37
+ s.add_dependency 'meilisearch', '~> 0.28'
38
38
  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.10.2
4
+ version: 0.14.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Meili
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-11 00:00:00.000000000 Z
11
+ date: 2024-09-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.26.0
19
+ version: '0.28'
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.26.0
26
+ version: '0.28'
27
27
  description: Meilisearch integration for Ruby on Rails. See https://github.com/meilisearch/meilisearch
28
28
  email: bonjour@meilisearch.com
29
29
  executables: []
@@ -40,7 +40,10 @@ files:
40
40
  - lib/meilisearch-rails.rb
41
41
  - lib/meilisearch/rails/configuration.rb
42
42
  - lib/meilisearch/rails/errors.rb
43
+ - lib/meilisearch/rails/ms_clean_up_job.rb
43
44
  - lib/meilisearch/rails/ms_job.rb
45
+ - lib/meilisearch/rails/multi_search.rb
46
+ - lib/meilisearch/rails/multi_search/result.rb
44
47
  - lib/meilisearch/rails/null_object.rb
45
48
  - lib/meilisearch/rails/pagination.rb
46
49
  - lib/meilisearch/rails/pagination/kaminari.rb
@@ -63,14 +66,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
63
66
  requirements:
64
67
  - - ">="
65
68
  - !ruby/object:Gem::Version
66
- version: 2.6.0
69
+ version: 3.0.0
67
70
  required_rubygems_version: !ruby/object:Gem::Requirement
68
71
  requirements:
69
72
  - - ">="
70
73
  - !ruby/object:Gem::Version
71
74
  version: '0'
72
75
  requirements: []
73
- rubygems_version: 3.1.6
76
+ rubygems_version: 3.4.19
74
77
  signing_key:
75
78
  specification_version: 4
76
79
  summary: Meilisearch integration for Ruby on Rails.