meilisearch-rails 0.7.2 → 0.8.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: affe6d35bf6c1c626570b32ae605e3b1e826c16c86e87d9ea4cc2e67cb4c1512
4
- data.tar.gz: b950799c5e8296d5fcbc2e194480cbbc4fa5a60b704708db55859f7d0a6d8e4c
3
+ metadata.gz: cd9b1257d27f252b6dc5caf4dcc3316d6b8e2a026b6266e4aec67eb05106ace0
4
+ data.tar.gz: 356acde3b6a894b8a3e8c2e2206c04527b5927968a33030a6f73e0d807f709af
5
5
  SHA512:
6
- metadata.gz: 7a84a8fbbb00122c28c90c5573f1e5a93a3012a89f516ea35df68eba294aea20b7e169906400ad27b17d281359a2d3fb5933eda1338aecb2941e206b21b00002
7
- data.tar.gz: c735267b627ef2100fc0cdd52bffa8d323d634b865c5ef5ba870d3839f8e2a0d03244e5478a056a26295fbd827c6ecbbd40a2994df8805fa194925add4c8533a
6
+ metadata.gz: a813264676828158494dd04f5192ab902fd735e3ef0bbc17960b9a8f54fdc581139ec528cd87c0883be6bc96becdce8d455c0055d31b0464f9ba0d53cfbf0751
7
+ data.tar.gz: 0b5c4276212a365b038de5492a606be125902bac3bb9417a7cdf279c6e8bccdc146eb84b991b3c8e55928ee99c99510934da0cbbe958813709b6af6725fd7922
data/Gemfile CHANGED
@@ -1,5 +1,7 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ # gem 'meilisearch', path: '../meilisearch-ruby'
4
+
3
5
  gemspec
4
6
 
5
7
  gem 'rubysl', '~> 2.0', platform: :rbx if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
@@ -29,6 +31,7 @@ group :test do
29
31
  gem 'jdbc-sqlite3', platform: :jruby
30
32
  gem 'rspec', '~> 3.0'
31
33
  gem 'simplecov', require: 'false'
34
+ gem 'threads'
32
35
 
33
36
  gem 'byebug'
34
37
  gem 'dotenv', '~> 2.7', '>= 2.7.6'
data/README.md CHANGED
@@ -23,18 +23,20 @@
23
23
 
24
24
  **Meilisearch Rails** is the Meilisearch integration for Ruby on Rails developers.
25
25
 
26
- **Meilisearch** is an open-source search engine. [Discover what Meilisearch is!](https://github.com/meilisearch/meilisearch)
26
+ **Meilisearch** is an open-source search engine. [Learn more about Meilisearch.](https://github.com/meilisearch/meilisearch)
27
27
 
28
28
  ## Table of Contents <!-- omit in toc -->
29
29
 
30
30
  - [📖 Documentation](#-documentation)
31
31
  - [🤖 Compatibility with Meilisearch](#-compatibility-with-meilisearch)
32
- - [🚀 Getting Started](#-getting-started)
32
+ - [🚀 Getting started](#-getting-started)
33
33
  - [Compatibility](#-compatibility)
34
34
  - [⚙️ Settings](#️-settings)
35
35
  - [🔍 Custom search](#-custom-search)
36
36
  - [🪛 Options](#-options)
37
37
  - [Meilisearch configuration & environment](#meilisearch-configuration--environment)
38
+ - [Pagination with `kaminari` or `will_paginate`](#backend-pagination-with-kaminari-or-will_paginate-)
39
+ - [Pagination with `pagy`](#backend-pagination-with-pagy-)
38
40
  - [Index configuration](#index-configuration)
39
41
  - [Custom attribute definition](#custom-attribute-definition)
40
42
  - [Custom primary key](#custom-primary-key)
@@ -60,7 +62,7 @@ To learn more about Meilisearch, check out our [Documentation](https://docs.meil
60
62
 
61
63
  ## 🤖 Compatibility with Meilisearch
62
64
 
63
- This package only guarantees the compatibility with the [version v0.28.0 of Meilisearch](https://github.com/meilisearch/meilisearch/releases/tag/v0.28.0).
65
+ This package only guarantees the compatibility with the [version v0.30.0 of Meilisearch](https://github.com/meilisearch/meilisearch/releases/tag/v0.30.0).
64
66
 
65
67
  ## 🔧 Installation <!-- omit in toc -->
66
68
 
@@ -91,7 +93,7 @@ docker run -it --rm -p 7700:7700 getmeili/meilisearch:latest meilisearch --maste
91
93
 
92
94
  NB: you can also download Meilisearch from **Homebrew** or **APT**.
93
95
 
94
- ## 🚀 Getting Started
96
+ ## 🚀 Getting started
95
97
 
96
98
  #### Configuration <!-- omit in toc -->
97
99
 
@@ -99,7 +101,7 @@ Create a new file `config/initializers/meilisearch.rb` to setup your `MEILISEARC
99
101
 
100
102
  ```ruby
101
103
  MeiliSearch::Rails.configuration = {
102
- meilisearch_host: 'YourMeilisearchHost', # example: http://localhost:7700
104
+ meilisearch_url: 'YourMeilisearchUrl', # example: http://localhost:7700
103
105
  meilisearch_api_key: 'YourMeilisearchAPIKey',
104
106
  }
105
107
  ```
@@ -138,46 +140,6 @@ hits.each do |hit|
138
140
  end
139
141
  ```
140
142
 
141
- #### Backend Pagination <!-- omit in toc -->
142
-
143
- This gem supports:
144
- - [kaminari](https://github.com/amatsuda/kaminari)
145
- - [pagy](https://github.com/ddnexus/pagy)
146
- - [will_paginate](https://github.com/mislav/will_paginate).
147
-
148
- Specify the `:pagination_backend` in the configuration file:
149
-
150
- ```ruby
151
- MeiliSearch::Rails.configuration = {
152
- meilisearch_host: 'YourMeilisearchHost',
153
- meilisearch_api_key: 'YourMeilisearchAPIKey',
154
- pagination_backend: :kaminari #:will_paginate
155
- }
156
- ```
157
-
158
- Then, as soon as you use the `search` method, the returning results will be paginated:
159
-
160
- ```ruby
161
- # controller
162
- @hits = Book.search('harry potter')
163
-
164
- # views
165
- <% @hits.each do |hit| %>
166
- <%= hit.title %>
167
- <%= hit.author %>
168
- <% end %>
169
-
170
- <%= paginate @hits %> # if using kaminari
171
-
172
- <%= will_paginate @hits %> # if using will_paginate
173
- ```
174
-
175
- The **number of hits per page defaults to 20**, you can customize it by adding the `hits_per_page` parameter to your search:
176
-
177
- ```ruby
178
- Book.search('harry potter', hits_per_page: 10)
179
- ```
180
-
181
143
  #### Extra Configuration <!-- omit in toc -->
182
144
 
183
145
  Requests made to Meilisearch may timeout and retry. To adapt the behavior to
@@ -185,7 +147,7 @@ your needs, you can change the parameters during configuration:
185
147
 
186
148
  ```ruby
187
149
  MeiliSearch::Rails.configuration = {
188
- meilisearch_host: 'YourMeilisearchHost',
150
+ meilisearch_url: 'YourMeilisearchUrl',
189
151
  meilisearch_api_key: 'YourMeilisearchAPIKey',
190
152
  timeout: 2,
191
153
  max_retries: 1,
@@ -223,6 +185,7 @@ class Book < ApplicationRecord
223
185
  attributes_to_highlight ['*']
224
186
  attributes_to_crop [:description]
225
187
  crop_length 10
188
+ pagination max_total_hits: 1000
226
189
  end
227
190
  end
228
191
  ```
@@ -254,6 +217,125 @@ Book.search('*', sort: ['title:asc'])
254
217
 
255
218
  ### Meilisearch configuration & environment
256
219
 
220
+ ### Backend Pagination with `kaminari` or `will_paginate` <!-- omit in toc -->
221
+
222
+ This gem supports:
223
+ - [kaminari](https://github.com/amatsuda/kaminari)
224
+ - [will_paginate](https://github.com/mislav/will_paginate)
225
+
226
+ Specify the `:pagination_backend` in the configuration file:
227
+
228
+ ```ruby
229
+ MeiliSearch::Rails.configuration = {
230
+ meilisearch_url: 'YourMeilisearchUrl',
231
+ meilisearch_api_key: 'YourMeilisearchAPIKey',
232
+ pagination_backend: :kaminari # :will_paginate
233
+ }
234
+ ```
235
+
236
+ Then, as soon as you use the `search` method, the returning results will be paginated:
237
+
238
+ ```ruby
239
+ # controller
240
+ @hits = Book.search('harry potter')
241
+
242
+ # views
243
+ <% @hits.each do |hit| %>
244
+ <%= hit.title %>
245
+ <%= hit.author %>
246
+ <% end %>
247
+
248
+ <%= paginate @hits %> # if using kaminari
249
+
250
+ <%= will_paginate @hits %> # if using will_paginate
251
+ ```
252
+
253
+ The **number of hits per page defaults to 20**, you can customize it by adding the `hits_per_page` parameter to your search:
254
+
255
+ ```ruby
256
+ Book.search('harry potter', hits_per_page: 10)
257
+ ```
258
+
259
+ ### Backend Pagination with `pagy` <!-- omit in toc -->
260
+
261
+ This gem supports [pagy](https://github.com/ddnexus/pagy) to paginate your search results.
262
+
263
+ To use `pagy` with your `meilisearch-rails` you need to:
264
+
265
+ Add the `pagy` gem to your Gemfile.
266
+ Create a new initializer `pagy.rb` with this:
267
+
268
+ ```rb
269
+ # config/initializers/pagy.rb
270
+
271
+ require 'pagy/extras/meilisearch'
272
+ ```
273
+
274
+ Then in your model you must extend `Pagy::Meilisearch`:
275
+
276
+ ```rb
277
+ class Book < ApplicationRecord
278
+ include MeiliSearch::Rails
279
+ extend Pagy::Meilisearch
280
+
281
+ meilisearch # ...
282
+ end
283
+ ```
284
+
285
+ And in your controller and view:
286
+
287
+ ```rb
288
+ # controllers/books_controller.rb
289
+ def search
290
+ hits = Book.pagy_search(params[:query])
291
+ @pagy, @hits = pagy_meilisearch(hits, items: 25)
292
+ end
293
+
294
+
295
+ # views/books/search.html.rb
296
+ <%== pagy_nav(@pagy) %>
297
+ ```
298
+
299
+ :warning: There is no need to set `pagination_backend` in the configuration block `MeiliSearch::Rails.configuration` for `pagy`.
300
+
301
+ Check [`ddnexus/pagy`](https://ddnexus.github.io/pagy/extras/meilisearch) for more information.
302
+
303
+ #### Deactivate Meilisearch in certain moments
304
+
305
+ 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>
306
+ you have multiple ways to achieve this.
307
+
308
+ By adding `active: false` in the configuration initializer:
309
+
310
+ ```ruby
311
+ MeiliSearch::Rails.configuration = {
312
+ meilisearch_url: 'YourMeilisearchUrl',
313
+ meilisearch_api_key: 'YourMeilisearchAPIKey',
314
+ active: false
315
+ }
316
+ ```
317
+
318
+ Or you can disable programmatically:
319
+
320
+ ```ruby
321
+ MeiliSearch::Rails.deactivate! # all the following HTTP calls will be dismissed.
322
+
323
+ # or you can pass a block to it:
324
+
325
+ MeiliSearch::Rails.deactivate! do
326
+ # every Meilisearch call here will be dismissed, no error will be raised.
327
+ # after the block, Meilisearch state will be active.
328
+ end
329
+ ```
330
+
331
+ You can also activate if you deactivated earlier:
332
+
333
+ ```ruby
334
+ MeiliSearch::Rails.activate!
335
+ ```
336
+
337
+ :warning: These calls are persistent, so prefer to use the method with the block. This way, you will not forget to activate it afterward.
338
+
257
339
  #### Custom index_uid <!-- omit in toc -->
258
340
 
259
341
  By default, the **index_uid** will be the class name, e.g. `Book`. You can customize the index_uid by using the `index_uid:` option.
@@ -272,7 +354,7 @@ You can suffix the index UID with the current Rails environment by setting it gl
272
354
 
273
355
  ```ruby
274
356
  MeiliSearch::Rails.configuration = {
275
- meilisearch_host: 'YourMeilisearchHost',
357
+ meilisearch_url: 'YourMeilisearchUrl',
276
358
  meilisearch_api_key: 'YourMeilisearchAPIKey',
277
359
  per_environment: true
278
360
  }
@@ -11,9 +11,41 @@ module MeiliSearch
11
11
  @_config = configuration
12
12
  end
13
13
 
14
+ def deactivate!
15
+ semaphore.synchronize do
16
+ @_config.merge!(active: false)
17
+
18
+ return unless block_given?
19
+
20
+ yield
21
+
22
+ @_config.merge!(active: true)
23
+ end
24
+ end
25
+
26
+ def activate!
27
+ semaphore.synchronize do
28
+ @_config.merge!(active: true)
29
+ end
30
+ end
31
+
32
+ def active?
33
+ configuration.fetch(:active, true)
34
+ end
35
+
36
+ def black_hole
37
+ @black_hole ||= NullObject.instance
38
+ end
39
+
40
+ def semaphore
41
+ @semaphore ||= Mutex.new
42
+ end
43
+
14
44
  def client
45
+ return black_hole unless active?
46
+
15
47
  ::MeiliSearch::Client.new(
16
- configuration[:meilisearch_host] || 'http://localhost:7700',
48
+ configuration[:meilisearch_url] || 'http://localhost:7700',
17
49
  configuration[:meilisearch_api_key],
18
50
  configuration.slice(:timeout, :max_retries)
19
51
  .merge(client_agents: MeiliSearch::Rails.qualified_version)
@@ -7,7 +7,7 @@ module MeiliSearch
7
7
  class NotConfigured < StandardError
8
8
  def message
9
9
  'Please configure Meilisearch. Set MeiliSearch::Rails.configuration = ' \
10
- "{meilisearch_host: 'YOUR_MEILISEARCH_HOST', meilisearch_api_key: 'YOUR_API_KEY'}"
10
+ "{meilisearch_url: 'YOUR_MEILISEARCH_URL', meilisearch_api_key: 'YOUR_API_KEY'}"
11
11
  end
12
12
  end
13
13
  end
@@ -0,0 +1,25 @@
1
+ require 'singleton'
2
+
3
+ module MeiliSearch
4
+ module Rails
5
+ class NullObject
6
+ include Singleton
7
+
8
+ def map
9
+ []
10
+ end
11
+
12
+ def nil?
13
+ true
14
+ end
15
+
16
+ def method_missing(_method, *_args, &_block)
17
+ self
18
+ end
19
+
20
+ def respond_to_missing?(_method_name, _include_private = false)
21
+ false
22
+ end
23
+ end
24
+ end
25
+ end
@@ -17,30 +17,18 @@ module MeiliSearch
17
17
  end
18
18
  end
19
19
 
20
- def limit(_num)
21
- # noop
22
- self
23
- end
24
-
25
- def offset(_num)
26
- # noop
27
- self
28
- end
20
+ def self.create(results, total_hits, options = {})
21
+ offset = ((options[:page] - 1) * options[:per_page])
22
+ array = new results, limit: options[:per_page], offset: offset, total_count: total_hits
29
23
 
30
- class << self
31
- def create(results, total_hits, options = {})
32
- offset = ((options[:page] - 1) * options[:per_page])
33
- array = new results, limit: options[:per_page], offset: offset, total_count: total_hits
34
-
35
- if array.empty? && !results.empty?
36
- # since Kaminari 0.16.0, you need to pad the results with nil values so it matches the offset param
37
- # otherwise you'll get an empty array: https://github.com/amatsuda/kaminari/commit/29fdcfa8865f2021f710adaedb41b7a7b081e34d
38
- results = ([nil] * offset) + results
39
- array = new results, offset: offset, limit: options[:per_page], total_count: total_hits
40
- end
41
-
42
- array
24
+ if array.empty? && !results.empty?
25
+ # since Kaminari 0.16.0, you need to pad the results with nil values so it matches the offset param
26
+ # otherwise you'll get an empty array: https://github.com/amatsuda/kaminari/commit/29fdcfa8865f2021f710adaedb41b7a7b081e34d
27
+ results = Array.new(offset) + results
28
+ array = new results, offset: offset, limit: options[:per_page], total_count: total_hits
43
29
  end
30
+
31
+ array
44
32
  end
45
33
  end
46
34
  end
@@ -11,9 +11,7 @@ module MeiliSearch
11
11
  class WillPaginate
12
12
  def self.create(results, total_hits, options = {})
13
13
  ::WillPaginate::Collection.create(options[:page], options[:per_page], total_hits) do |pager|
14
- start = (options[:page] - 1) * options[:per_page]
15
- paginated_results = results[start, options[:per_page]]
16
- pager.replace paginated_results
14
+ pager.replace results
17
15
  end
18
16
  end
19
17
  end
@@ -5,15 +5,28 @@ module MeiliSearch
5
5
  autoload :Kaminari, 'meilisearch/rails/pagination/kaminari'
6
6
 
7
7
  def self.create(results, total_hits, options = {})
8
- return results if MeiliSearch::Rails.configuration[:pagination_backend].nil?
8
+ pagination_backend = MeiliSearch::Rails.configuration[:pagination_backend]
9
9
 
10
- begin
11
- backend = MeiliSearch::Rails.configuration[:pagination_backend].to_s.classify
10
+ if pagination_backend.nil? || (is_pagy = pagination_backend.to_s == 'pagy')
11
+ log_pagy_error if is_pagy
12
12
 
13
- ::MeiliSearch::Rails::Pagination.const_get(backend).create(results, total_hits, options)
14
- rescue NameError
15
- raise(BadConfiguration, 'Unknown pagination backend')
13
+ return results
16
14
  end
15
+
16
+ load_pagination!(pagination_backend, results, total_hits, options)
17
+ end
18
+
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`')
22
+ end
23
+
24
+ def self.load_pagination!(pagination_backend, results, total_hits, options)
25
+ ::MeiliSearch::Rails::Pagination
26
+ .const_get(pagination_backend.to_s.classify)
27
+ .create(results, total_hits, options)
28
+ rescue NameError
29
+ raise(BadConfiguration, 'Invalid `pagination_backend:` configuration, check your initializer.')
17
30
  end
18
31
  end
19
32
  end
@@ -40,6 +40,31 @@ module MeiliSearch
40
40
  klass.ms_set_settings
41
41
  end
42
42
  end
43
+
44
+ def indexable?(record, options)
45
+ return false unless options[:if].blank? || constraint_passes?(record, options[:if])
46
+ return false unless options[:unless].blank? || !constraint_passes?(record, options[:unless])
47
+
48
+ true
49
+ end
50
+
51
+ private
52
+
53
+ def constraint_passes?(record, constraint)
54
+ case constraint
55
+ when Symbol
56
+ record.send(constraint)
57
+ when String
58
+ record.send(constraint.to_sym)
59
+ when Enumerable
60
+ # All constraints must pass
61
+ constraint.all? { |inner_constraint| constraint_passes?(record, inner_constraint) }
62
+ else
63
+ raise ArgumentError, "Unknown constraint type: #{constraint} (#{constraint.class})" unless constraint.respond_to?(:call)
64
+
65
+ constraint.call(record)
66
+ end
67
+ end
43
68
  end
44
69
  end
45
70
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module MeiliSearch
4
4
  module Rails
5
- VERSION = '0.7.2'
5
+ VERSION = '0.8.0'
6
6
 
7
7
  def self.qualified_version
8
8
  "Meilisearch Rails (v#{VERSION})"
@@ -1,5 +1,5 @@
1
1
  require 'meilisearch'
2
-
2
+ require 'meilisearch/rails/null_object'
3
3
  require 'meilisearch/rails/version'
4
4
  require 'meilisearch/rails/utilities'
5
5
  require 'meilisearch/rails/errors'
@@ -59,8 +59,11 @@ module MeiliSearch
59
59
  attributesToHighlight
60
60
  attributesToCrop
61
61
  cropLength
62
+ pagination
62
63
  ].freeze
63
64
 
65
+ CAMELIZE_OPTIONS = %i[pagination].freeze
66
+
64
67
  OPTIONS.each do |option|
65
68
  define_method option do |value|
66
69
  instance_variable_set("@#{option}", value)
@@ -199,7 +202,13 @@ module MeiliSearch
199
202
  settings = {}
200
203
  OPTIONS.each do |k|
201
204
  v = get_setting(k)
202
- settings[k] = v unless v.nil?
205
+ next if v.nil?
206
+
207
+ settings[k] = if CAMELIZE_OPTIONS.include?(k) && v.is_a?(Hash)
208
+ v.transform_keys { |key| key.to_s.camelize(:lower) }
209
+ else
210
+ v
211
+ end
203
212
  end
204
213
  settings
205
214
  end
@@ -249,7 +258,10 @@ module MeiliSearch
249
258
  args[0].delete(:attributesToCrop) if args[0][:attributesToCrop]
250
259
  args[0].delete(:cropLength) if args[0][:cropLength]
251
260
  end
261
+
252
262
  SafeIndex.log_or_throw(m, @raise_on_failure) do
263
+ return MeiliSearch::Rails.black_hole unless MeiliSearch::Rails.active?
264
+
253
265
  @index.send(m, *args, &block)
254
266
  end
255
267
  end
@@ -281,7 +293,7 @@ module MeiliSearch
281
293
  raise e if raise_on_failure
282
294
 
283
295
  # log the error
284
- (::Rails.logger || Logger.new($stdout)).error("[meilisearch-rails] #{e.message}")
296
+ (::Rails.logger || Logger.new($stdout)).info("[meilisearch-rails] #{e.message}")
285
297
  # return something
286
298
  case method.to_s
287
299
  when 'search'
@@ -342,7 +354,7 @@ module MeiliSearch
342
354
  end
343
355
  end
344
356
  if options[:enqueue]
345
- raise ArgumentError, 'Cannot use a enqueue if the `synchronous` option if set' if options[:synchronous]
357
+ raise ArgumentError, 'Cannot use a enqueue if the `synchronous` option is set' if options[:synchronous]
346
358
 
347
359
  proc = if options[:enqueue] == true
348
360
  proc do |record, remove|
@@ -452,10 +464,10 @@ module MeiliSearch
452
464
  ms_find_in_batches(batch_size) do |group|
453
465
  if ms_conditional_index?(options)
454
466
  # delete non-indexable documents
455
- ids = group.select { |d| !ms_indexable?(d, options) }.map { |d| ms_primary_key_of(d, options) }
467
+ ids = group.select { |d| !Utilities.indexable?(d, options) }.map { |d| ms_primary_key_of(d, options) }
456
468
  index.delete_documents(ids.select(&:present?))
457
469
  # select only indexable documents
458
- group = group.select { |d| ms_indexable?(d, options) }
470
+ group = group.select { |d| Utilities.indexable?(d, options) }
459
471
  end
460
472
  documents = group.map do |d|
461
473
  attributes = settings.get_attributes(d)
@@ -502,7 +514,7 @@ module MeiliSearch
502
514
 
503
515
  primary_key = ms_primary_key_of(document, options)
504
516
  index = ms_ensure_init(options, settings)
505
- if ms_indexable?(document, options)
517
+ if Utilities.indexable?(document, options)
506
518
  raise ArgumentError, 'Cannot index a record without a primary key' if primary_key.blank?
507
519
 
508
520
  doc = settings.get_attributes(document)
@@ -550,7 +562,7 @@ module MeiliSearch
550
562
 
551
563
  index = ms_ensure_init(options, settings)
552
564
  synchronous || options[:synchronous] ? index.delete_all_documents! : index.delete_all_documents
553
- @ms_indexes[settings] = nil
565
+ @ms_indexes[MeiliSearch::Rails.active?][settings] = nil
554
566
  end
555
567
  nil
556
568
  end
@@ -599,18 +611,15 @@ module MeiliSearch
599
611
 
600
612
  def ms_search(query, params = {})
601
613
  if MeiliSearch::Rails.configuration[:pagination_backend]
602
- page = params[:page].nil? ? params[:page] : params[:page].to_i
603
- hits_per_page = params[:hitsPerPage].nil? ? params[:hitsPerPage] : params[:hitsPerPage].to_i
604
- hits_per_page ||= params[:hits_per_page].nil? ? params[:hits_per_page] : params[:hits_per_page].to_i
605
-
606
- %i[page hitsPerPage hits_per_page].each { |param| params.delete(param) }
614
+ %i[page hitsPerPage hits_per_page].each do |key|
615
+ params[key.to_s.underscore.to_sym] = params[key].to_i if params.key?(key)
616
+ end
607
617
 
608
- params[:limit] = 200
618
+ # It is required to activate the finite pagination in Meilisearch v0.30 (or newer),
619
+ # to have at least `hits_per_page` defined or `page` in the search request.
620
+ params[:page] ||= 1
609
621
  end
610
622
 
611
- # Returns raw json hits as follows:
612
- # {"hits"=>[{"id"=>"13", "href"=>"apple", "name"=>"iphone"}], "offset"=>0, "limit"=>|| 20, "estimatedTotalHits"=>1,
613
- # "processingTimeMs"=>0, "query"=>"iphone"}
614
623
  json = ms_raw_search(query, params)
615
624
 
616
625
  # condition_key gets the primary key of the document; looks for "id" on the options
@@ -653,11 +662,7 @@ module MeiliSearch
653
662
  end
654
663
  end.compact
655
664
 
656
- total_hits = json['hits'].length
657
- hits_per_page ||= 20
658
- page ||= 1
659
-
660
- res = MeiliSearch::Rails::Pagination.create(results, total_hits, meilisearch_options.merge(page: page, per_page: hits_per_page))
665
+ res = Pagination.create(results, json['totalHits'], meilisearch_options.merge(page: json['page'], per_page: json['hitsPerPage']))
661
666
  res.extend(AdditionalMethods)
662
667
  res.send(:ms_init_raw_answer, json)
663
668
  res
@@ -720,16 +725,16 @@ module MeiliSearch
720
725
  def ms_ensure_init(options = nil, settings = nil, index_settings = nil)
721
726
  raise ArgumentError, 'No `meilisearch` block found in your model.' if meilisearch_settings.nil?
722
727
 
723
- @ms_indexes ||= {}
728
+ @ms_indexes ||= { true => {}, false => {} }
724
729
 
725
730
  options ||= meilisearch_options
726
731
  settings ||= meilisearch_settings
727
732
 
728
- return @ms_indexes[settings] if @ms_indexes[settings]
733
+ return @ms_indexes[MeiliSearch::Rails.active?][settings] if @ms_indexes[MeiliSearch::Rails.active?][settings]
729
734
 
730
- @ms_indexes[settings] = SafeIndex.new(ms_index_uid(options), meilisearch_options[:raise_on_failure], meilisearch_options)
735
+ @ms_indexes[MeiliSearch::Rails.active?][settings] = SafeIndex.new(ms_index_uid(options), meilisearch_options[:raise_on_failure], meilisearch_options)
731
736
 
732
- current_settings = @ms_indexes[settings].settings(getVersion: 1) rescue nil # if the index doesn't exist
737
+ current_settings = @ms_indexes[MeiliSearch::Rails.active?][settings].settings(getVersion: 1) rescue nil # if the index doesn't exist
733
738
 
734
739
  index_settings ||= settings.to_settings
735
740
  index_settings = options[:primary_settings].to_settings.merge(index_settings) if options[:inherit]
@@ -737,10 +742,10 @@ module MeiliSearch
737
742
  options[:check_settings] = true if options[:check_settings].nil?
738
743
 
739
744
  if !ms_indexing_disabled?(options) && options[:check_settings] && meilisearch_settings_changed?(current_settings, index_settings)
740
- @ms_indexes[settings].update_settings(index_settings)
745
+ @ms_indexes[MeiliSearch::Rails.active?][settings].update_settings(index_settings)
741
746
  end
742
747
 
743
- @ms_indexes[settings]
748
+ @ms_indexes[MeiliSearch::Rails.active?][settings]
744
749
  end
745
750
 
746
751
  private
@@ -802,31 +807,6 @@ module MeiliSearch
802
807
  options[:if].present? || options[:unless].present?
803
808
  end
804
809
 
805
- def ms_indexable?(document, options = nil)
806
- options ||= meilisearch_options
807
- if_passes = options[:if].blank? || ms_constraint_passes?(document, options[:if])
808
- unless_passes = options[:unless].blank? || !ms_constraint_passes?(document, options[:unless])
809
- if_passes && unless_passes
810
- end
811
-
812
- def ms_constraint_passes?(document, constraint)
813
- case constraint
814
- when Symbol
815
- document.send(constraint)
816
- when String
817
- document.send(constraint.to_sym)
818
- when Enumerable
819
- # All constraints must pass
820
- constraint.all? { |inner_constraint| ms_constraint_passes?(document, inner_constraint) }
821
- else
822
- unless constraint.respond_to?(:call)
823
- raise ArgumentError, "Unknown constraint type: #{constraint} (#{constraint.class})"
824
- end
825
-
826
- constraint.call(document)
827
- end
828
- end
829
-
830
810
  def ms_indexing_disabled?(options = nil)
831
811
  options ||= meilisearch_options
832
812
  constraint = options[:disable_indexing] || options['disable_indexing']
@@ -902,6 +882,8 @@ module MeiliSearch
902
882
  end
903
883
 
904
884
  def ms_enqueue_index!(synchronous)
885
+ return unless Utilities.indexable?(self, meilisearch_options)
886
+
905
887
  if meilisearch_options[:enqueue]
906
888
  unless self.class.send(:ms_indexing_disabled?, meilisearch_options)
907
889
  meilisearch_options[:enqueue].call(self, false)
@@ -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.19.2'
37
+ s.add_dependency 'meilisearch', '~> 0.21.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.7.2
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Meili
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-18 00:00:00.000000000 Z
11
+ date: 2022-12-01 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.19.2
19
+ version: 0.21.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.19.2
26
+ version: 0.21.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: []
@@ -41,6 +41,7 @@ files:
41
41
  - lib/meilisearch/rails/configuration.rb
42
42
  - lib/meilisearch/rails/errors.rb
43
43
  - lib/meilisearch/rails/ms_job.rb
44
+ - lib/meilisearch/rails/null_object.rb
44
45
  - lib/meilisearch/rails/pagination.rb
45
46
  - lib/meilisearch/rails/pagination/kaminari.rb
46
47
  - lib/meilisearch/rails/pagination/will_paginate.rb