meilisearch-rails 0.7.2 → 0.8.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: 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