meilisearch-rails 0.10.1 → 0.11.0

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: 5533b797c2c1df4ba52eee7e73d68c81b8a329353b896d7e5d6b17560f2b9c6d
4
- data.tar.gz: c65d9fc11a89d2d054392b44c8858b59429e84fc707f569ba7d3888c4685c0df
3
+ metadata.gz: 215428bdb5e437c3a906e1246444dc7e2afce9d2b52646790de1d55d0490783f
4
+ data.tar.gz: 412f8d56c952a330a9b3473602aca9ac0fee6789a3a3632f65340c7c85524637
5
5
  SHA512:
6
- metadata.gz: f86c37174ef35dce271cc4dbd0ef51355828e9c1bb16c266b019883afc7fb1856f73b4d6dd61982c74e41c716122684d7307a31ee86d0015b3538bbc3c3f6616
7
- data.tar.gz: 88038b5cae1f6611e4793cf5051f03f88e9c01683bde793c38134340eb68126b38d3784b3e73bf7b79b07e0bbdf9d44d08c08938abee35b7a950728f6fc4c43b
6
+ metadata.gz: ad8f9e4489c11dd3b2a522b134921232fbe2b66946f57ebf6be0c18ccd0643490379fb483d0a2ecf3371a427ff442809801130308e8f11fdedc7d6869a8d14c5
7
+ data.tar.gz: 5473ca9c267a3dfada14258db095d86c2e3618d356afc29ecf60c6975b067078cac91d8cc84c3e0b0bf8b5f227496d95830d77ed41923d0deeb313165b0b37df
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
@@ -29,7 +29,7 @@
29
29
 
30
30
  **Meilisearch** is an open-source search engine. [Learn more about Meilisearch.](https://github.com/meilisearch/meilisearch)
31
31
 
32
- ## Table of Contents <!-- omit in toc -->
32
+ ## Table of Contents <!-- omit in TOC -->
33
33
 
34
34
  - [📖 Documentation](#-documentation)
35
35
  - [⚡ Supercharge your Meilisearch experience](#-supercharge-your-meilisearch-experience)
@@ -329,7 +329,7 @@ Check [`ddnexus/pagy`](https://ddnexus.github.io/pagy/extras/meilisearch) for mo
329
329
 
330
330
  #### Deactivate Meilisearch in certain moments
331
331
 
332
- By default HTTP connections to the Meilisearch URL is always active, but sometimes you want to disable the HTTP requests in a particular moment or environment.<br>
332
+ By default, HTTP connections to the Meilisearch URL are always active, but sometimes you want to disable the HTTP requests in a particular moment or environment.<br>
333
333
  you have multiple ways to achieve this.
334
334
 
335
335
  By adding `active: false` in the configuration initializer:
@@ -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])
12
+ else
13
+ index.delete_document(document[:primary_key])
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -17,8 +17,8 @@ module MeiliSearch
17
17
  end
18
18
 
19
19
  def self.log_pagy_error
20
- (::Rails.logger || Logger.new($stdout))
21
- .warning('[meilisearch-rails] Remove `pagination_backend: :pagy` from your initializer, `pagy` it is not required for `pagy`')
20
+ MeiliSearch::Rails.logger
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)
@@ -2,7 +2,7 @@
2
2
 
3
3
  module MeiliSearch
4
4
  module Rails
5
- VERSION = '0.10.1'
5
+ VERSION = '0.11.0'
6
6
 
7
7
  def self.qualified_version
8
8
  "Meilisearch Rails (v#{VERSION})"
@@ -39,6 +39,10 @@ module MeiliSearch
39
39
  include InstanceMethods
40
40
  end
41
41
  end
42
+
43
+ def logger
44
+ @logger ||= (::Rails.logger || Logger.new($stdout))
45
+ end
42
46
  end
43
47
 
44
48
  class IndexSettings
@@ -245,6 +249,7 @@ module MeiliSearch
245
249
  # lazy load the ActiveJob class to ensure the
246
250
  # queue is initialized before using it
247
251
  autoload :MSJob, 'meilisearch/rails/ms_job'
252
+ autoload :MSCleanUpJob, 'meilisearch/rails/ms_clean_up_job'
248
253
  end
249
254
 
250
255
  # this class wraps an MeiliSearch::Index document ensuring all raised exceptions
@@ -256,7 +261,7 @@ module MeiliSearch
256
261
  @raise_on_failure = raise_on_failure.nil? || raise_on_failure
257
262
 
258
263
  SafeIndex.log_or_throw(nil, @raise_on_failure) do
259
- client.create_index(index_uid, { primary_key: primary_key })
264
+ client.create_index!(index_uid, { primary_key: primary_key })
260
265
  end
261
266
 
262
267
  @index = client.index(index_uid)
@@ -278,6 +283,15 @@ module MeiliSearch
278
283
  end
279
284
  end
280
285
 
286
+ # Maually define facet_search due to complications with **opts in ruby 2.*
287
+ def facet_search(*args, **opts)
288
+ SafeIndex.log_or_throw(:facet_search, @raise_on_failure) do
289
+ return MeiliSearch::Rails.black_hole unless MeiliSearch::Rails.active?
290
+
291
+ @index.facet_search(*args, **opts)
292
+ end
293
+ end
294
+
281
295
  # special handling of wait_for_task to handle null task_id
282
296
  def wait_for_task(task_uid)
283
297
  return if task_uid.nil? && !@raise_on_failure # ok
@@ -304,7 +318,7 @@ module MeiliSearch
304
318
  raise e if raise_on_failure
305
319
 
306
320
  # log the error
307
- (::Rails.logger || Logger.new($stdout)).info("[meilisearch-rails] #{e.message}")
321
+ MeiliSearch::Rails.logger.info("[meilisearch-rails] #{e.message}")
308
322
  # return something
309
323
  case method.to_s
310
324
  when 'search'
@@ -369,7 +383,11 @@ module MeiliSearch
369
383
 
370
384
  proc = if options[:enqueue] == true
371
385
  proc do |record, remove|
372
- MSJob.perform_later(record, remove ? 'ms_remove_from_index!' : 'ms_index!')
386
+ if remove
387
+ MSCleanUpJob.perform_later(record.ms_entries)
388
+ else
389
+ MSJob.perform_later(record, 'ms_index!')
390
+ end
373
391
  end
374
392
  elsif options[:enqueue].respond_to?(:call)
375
393
  options[:enqueue]
@@ -441,9 +459,11 @@ module MeiliSearch
441
459
  end
442
460
  end
443
461
  elsif respond_to?(:after_destroy)
444
- after_destroy { |searchable| searchable.ms_enqueue_remove_from_index!(ms_synchronous?) }
462
+ after_destroy_commit { |searchable| searchable.ms_enqueue_remove_from_index!(ms_synchronous?) }
445
463
  end
446
464
  end
465
+
466
+ warn_searchable_missing_attributes
447
467
  end
448
468
 
449
469
  def ms_without_auto_index(&block)
@@ -520,7 +540,8 @@ module MeiliSearch
520
540
  def ms_index!(document, synchronous = false)
521
541
  return if ms_without_auto_index_scope
522
542
 
523
- ms_configurations.each do |options, settings|
543
+ # MS tasks to be returned
544
+ ms_configurations.map do |options, settings|
524
545
  next if ms_indexing_disabled?(options)
525
546
 
526
547
  primary_key = ms_primary_key_of(document, options)
@@ -544,8 +565,20 @@ module MeiliSearch
544
565
  index.delete_document(primary_key)
545
566
  end
546
567
  end
568
+ end.compact
569
+ end
570
+
571
+ def ms_entries_for(document:, synchronous:)
572
+ primary_key = ms_primary_key_of(document)
573
+ raise ArgumentError, 'Cannot index a record without a primary key' if primary_key.blank?
574
+
575
+ ms_configurations.filter_map do |options, settings|
576
+ {
577
+ synchronous: synchronous || options[:synchronous],
578
+ index_uid: options[:index_uid],
579
+ primary_key: primary_key
580
+ }.with_indifferent_access unless ms_indexing_disabled?(options)
547
581
  end
548
- nil
549
582
  end
550
583
 
551
584
  def ms_remove_from_index!(document, synchronous = false)
@@ -729,33 +762,38 @@ module MeiliSearch
729
762
 
730
763
  protected
731
764
 
732
- def ms_ensure_init(options = nil, settings = nil, index_settings = nil)
765
+ def ms_ensure_init(options = meilisearch_options, settings = meilisearch_settings, user_configuration = settings.to_settings)
733
766
  raise ArgumentError, 'No `meilisearch` block found in your model.' if meilisearch_settings.nil?
734
767
 
735
768
  @ms_indexes ||= { true => {}, false => {} }
736
769
 
737
- options ||= meilisearch_options
738
- settings ||= meilisearch_settings
770
+ @ms_indexes[MeiliSearch::Rails.active?][settings] ||= SafeIndex.new(ms_index_uid(options), meilisearch_options[:raise_on_failure], meilisearch_options)
739
771
 
740
- return @ms_indexes[MeiliSearch::Rails.active?][settings] if @ms_indexes[MeiliSearch::Rails.active?][settings]
772
+ update_settings_if_changed(@ms_indexes[MeiliSearch::Rails.active?][settings], options, user_configuration)
741
773
 
742
- @ms_indexes[MeiliSearch::Rails.active?][settings] = SafeIndex.new(ms_index_uid(options), meilisearch_options[:raise_on_failure], meilisearch_options)
774
+ @ms_indexes[MeiliSearch::Rails.active?][settings]
775
+ end
743
776
 
744
- current_settings = @ms_indexes[MeiliSearch::Rails.active?][settings].settings(getVersion: 1) rescue nil # if the index doesn't exist
777
+ private
745
778
 
746
- index_settings ||= settings.to_settings
747
- index_settings = options[:primary_settings].to_settings.merge(index_settings) if options[:inherit]
779
+ def update_settings_if_changed(index, options, user_configuration)
780
+ server_state = index.settings
781
+ user_configuration = options[:primary_settings].to_settings.merge(user_configuration) if options[:inherit]
748
782
 
749
- options[:check_settings] = true if options[:check_settings].nil?
783
+ config = user_configuration.except(:attributes_to_highlight, :attributes_to_crop, :crop_length)
750
784
 
751
- if !ms_indexing_disabled?(options) && options[:check_settings] && meilisearch_settings_changed?(current_settings, index_settings)
752
- @ms_indexes[MeiliSearch::Rails.active?][settings].update_settings(index_settings)
785
+ if !skip_checking_settings?(options) && meilisearch_settings_changed?(server_state, config)
786
+ index.update_settings(user_configuration)
753
787
  end
788
+ end
754
789
 
755
- @ms_indexes[MeiliSearch::Rails.active?][settings]
790
+ def skip_checking_settings?(options)
791
+ ms_indexing_disabled?(options) || ms_checking_disabled?(options)
756
792
  end
757
793
 
758
- private
794
+ def ms_checking_disabled?(options)
795
+ options[:check_settings] == false
796
+ end
759
797
 
760
798
  def ms_configurations
761
799
  raise ArgumentError, 'No `meilisearch` block found in your model.' if meilisearch_settings.nil?
@@ -794,19 +832,22 @@ module MeiliSearch
794
832
  options[:primary_key] || MeiliSearch::Rails::IndexSettings::DEFAULT_PRIMARY_KEY
795
833
  end
796
834
 
797
- def meilisearch_settings_changed?(prev, current)
798
- return true if prev.nil?
835
+ def meilisearch_settings_changed?(server_state, user_configuration)
836
+ return true if server_state.nil?
837
+
838
+ user_configuration.transform_keys! { |key| key.to_s.camelize(:lower) }
799
839
 
800
- current.each do |k, v|
801
- prev_v = prev[k.to_s]
802
- if v.is_a?(Array) && prev_v.is_a?(Array)
803
- # compare array of strings, avoiding symbols VS strings comparison
804
- return true if v.map(&:to_s) != prev_v.map(&:to_s)
805
- elsif prev_v != v
806
- return true
840
+ user_configuration.any? do |key, user|
841
+ server = server_state[key]
842
+
843
+ if user.is_a?(Hash) && server.is_a?(Hash)
844
+ meilisearch_settings_changed?(server, user)
845
+ elsif user.is_a?(Array) && server.is_a?(Array)
846
+ user.map(&:to_s) != server.map(&:to_s)
847
+ else
848
+ user.to_s != server.to_s
807
849
  end
808
850
  end
809
- false
810
851
  end
811
852
 
812
853
  def ms_conditional_index?(options = nil)
@@ -858,6 +899,19 @@ module MeiliSearch
858
899
  # We don't know if the attribute has changed, so conservatively assume it has
859
900
  true
860
901
  end
902
+
903
+ def warn_searchable_missing_attributes
904
+ searchables = meilisearch_settings.get_setting(:searchable_attributes)
905
+ attrs = meilisearch_settings.get_setting(:attributes)&.keys
906
+
907
+ if searchables.present? && attrs.present?
908
+ (searchables.map(&:to_s) - attrs.map(&:to_s)).each do |missing_searchable|
909
+ MeiliSearch::Rails.logger.warn(
910
+ "[meilisearch-rails] #{name}##{missing_searchable} declared in searchable_attributes but not in attributes. Please add it to attributes if it should be searchable."
911
+ )
912
+ end
913
+ end
914
+ end
861
915
  end
862
916
 
863
917
  # these are the instance methods included
@@ -904,6 +958,10 @@ module MeiliSearch
904
958
  @ms_synchronous
905
959
  end
906
960
 
961
+ def ms_entries(synchronous = false)
962
+ self.class.ms_entries_for(document: self, synchronous: synchronous || ms_synchronous?)
963
+ end
964
+
907
965
  private
908
966
 
909
967
  def ms_mark_synchronous
@@ -34,5 +34,5 @@ Gem::Specification.new do |s|
34
34
 
35
35
  s.required_ruby_version = '>= 2.6.0'
36
36
 
37
- s.add_dependency 'meilisearch', '~> 0.25.0'
37
+ s.add_dependency 'meilisearch', '~> 0.26.0'
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.1
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Meili
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-14 00:00:00.000000000 Z
11
+ date: 2024-02-12 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.25.0
19
+ version: 0.26.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.25.0
26
+ version: 0.26.0
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,6 +40,7 @@ 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
44
45
  - lib/meilisearch/rails/null_object.rb
45
46
  - lib/meilisearch/rails/pagination.rb
@@ -70,7 +71,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
70
71
  - !ruby/object:Gem::Version
71
72
  version: '0'
72
73
  requirements: []
73
- rubygems_version: 3.0.3.1
74
+ rubygems_version: 3.1.6
74
75
  signing_key:
75
76
  specification_version: 4
76
77
  summary: Meilisearch integration for Ruby on Rails.