Commit b9948a09fd60646e208b94925093b5e023f95c52
1 parent
2c49d184
Exists in
master
and in
2 other branches
Added unscope option to better support working with default scopes
Showing
11 changed files
with
87 additions
and
2 deletions
Show diff stats
CHANGELOG.md
1 | 1 | ## 5.0.0 (unreleased) |
2 | 2 | |
3 | 3 | - Searches now use lazy loading (similar to Active Record) |
4 | +- Added `unscope` option to better support working with default scopes | |
4 | 5 | - Added support for `:async` and `:queue` modes for `reindex` on relation |
5 | 6 | - Added basic protection from unfiltered parameters to `where` option |
6 | 7 | - Added `models` option to `similar` method | ... | ... |
lib/searchkick.rb
... | ... | @@ -315,6 +315,18 @@ module Searchkick |
315 | 315 | end |
316 | 316 | |
317 | 317 | # private |
318 | + def self.scope(model) | |
319 | + # safety check to make sure used properly in code | |
320 | + raise Error, "Cannot scope relation" if relation?(model) | |
321 | + | |
322 | + if model.searchkick_options[:unscope] | |
323 | + model.unscoped | |
324 | + else | |
325 | + model | |
326 | + end | |
327 | + end | |
328 | + | |
329 | + # private | |
318 | 330 | def self.not_found_error?(e) |
319 | 331 | (defined?(Elastic::Transport) && e.is_a?(Elastic::Transport::Transport::Errors::NotFound)) || |
320 | 332 | (defined?(Elasticsearch::Transport) && e.is_a?(Elasticsearch::Transport::Transport::Errors::NotFound)) || | ... | ... |
lib/searchkick/bulk_reindex_job.rb
lib/searchkick/model.rb
... | ... | @@ -7,7 +7,7 @@ module Searchkick |
7 | 7 | :filterable, :geo_shape, :highlight, :ignore_above, :index_name, :index_prefix, :inheritance, :language, |
8 | 8 | :locations, :mappings, :match, :merge_mappings, :routing, :searchable, :search_synonyms, :settings, :similarity, |
9 | 9 | :special_characters, :stem, :stemmer, :stem_conversions, :stem_exclusion, :stemmer_override, :suggest, :synonyms, :text_end, |
10 | - :text_middle, :text_start, :word, :word_end, :word_middle, :word_start] | |
10 | + :text_middle, :text_start, :unscope, :word, :word_end, :word_middle, :word_start] | |
11 | 11 | raise ArgumentError, "unknown keywords: #{unknown_keywords.join(", ")}" if unknown_keywords.any? |
12 | 12 | |
13 | 13 | raise "Only call searchkick once per model" if respond_to?(:searchkick_index) |
... | ... | @@ -78,7 +78,7 @@ module Searchkick |
78 | 78 | def searchkick_reindex(method_name = nil, **options) |
79 | 79 | scoped = Searchkick.relation?(self) |
80 | 80 | # call searchkick_klass for inheritance |
81 | - relation = scoped ? all : searchkick_klass.all | |
81 | + relation = scoped ? all : Searchkick.scope(searchkick_klass).all | |
82 | 82 | # prevent scope from affecting search_data |
83 | 83 | unscoped do |
84 | 84 | searchkick_index.reindex(relation, method_name, scoped: scoped, **options) | ... | ... |
lib/searchkick/process_batch_job.rb
lib/searchkick/reindex_v2_job.rb
... | ... | @@ -6,6 +6,8 @@ module Searchkick |
6 | 6 | model = klass.constantize |
7 | 7 | # use should_index? to decide whether to index (not default scope) |
8 | 8 | # just like saving inline |
9 | + # could use Searchkick.scope() in future | |
10 | + # but keep for now for backwards compatibility | |
9 | 11 | model = model.unscoped if model.respond_to?(:unscoped) |
10 | 12 | items = [{id: id, routing: routing}] |
11 | 13 | model.searchkick_index.send(:record_indexer).reindex_items(model, items, method_name: method_name, single: true) | ... | ... |
lib/searchkick/results.rb
test/support/activerecord.rb
... | ... | @@ -65,6 +65,12 @@ ActiveRecord::Schema.define do |
65 | 65 | t.string :name |
66 | 66 | t.boolean :active |
67 | 67 | end |
68 | + | |
69 | + create_table :artists do |t| | |
70 | + t.string :name | |
71 | + t.boolean :active | |
72 | + t.boolean :should_index | |
73 | + end | |
68 | 74 | end |
69 | 75 | |
70 | 76 | class Product < ActiveRecord::Base |
... | ... | @@ -99,3 +105,7 @@ end |
99 | 105 | class Band < ActiveRecord::Base |
100 | 106 | default_scope { where(active: true).order(:name) } |
101 | 107 | end |
108 | + | |
109 | +class Artist < ActiveRecord::Base | |
110 | + default_scope { where(active: true).order(:name) } | |
111 | +end | ... | ... |
test/support/mongoid.rb
... | ... | @@ -75,3 +75,13 @@ class Band |
75 | 75 | |
76 | 76 | default_scope -> { where(active: true).order(name: 1) } |
77 | 77 | end |
78 | + | |
79 | +class Artist | |
80 | + include Mongoid::Document | |
81 | + | |
82 | + field :name | |
83 | + field :active, type: Mongoid::Boolean | |
84 | + field :should_index, type: Mongoid::Boolean | |
85 | + | |
86 | + default_scope -> { where(active: true).order(name: 1) } | |
87 | +end | ... | ... |
... | ... | @@ -0,0 +1,39 @@ |
1 | +require_relative "test_helper" | |
2 | + | |
3 | +class UnscopeTest < ActiveSupport::TestCase | |
4 | + def setup | |
5 | + @@once ||= Artist.reindex | |
6 | + | |
7 | + Artist.unscoped.destroy_all | |
8 | + end | |
9 | + | |
10 | + def test_reindex | |
11 | + create_records | |
12 | + | |
13 | + Artist.reindex | |
14 | + assert_search "*", ["Test", "Test 2"] | |
15 | + assert_search "*", ["Test", "Test 2"], {load: false} | |
16 | + end | |
17 | + | |
18 | + def test_relation_async | |
19 | + create_records | |
20 | + | |
21 | + Artist.unscoped.reindex(mode: :async) | |
22 | + perform_enqueued_jobs | |
23 | + | |
24 | + Artist.search_index.refresh | |
25 | + assert_search "*", ["Test", "Test 2"] | |
26 | + end | |
27 | + | |
28 | + def create_records | |
29 | + store [ | |
30 | + {name: "Test", active: true, should_index: true}, | |
31 | + {name: "Test 2", active: false, should_index: true}, | |
32 | + {name: "Test 3", active: false, should_index: false}, | |
33 | + ], reindex: false | |
34 | + end | |
35 | + | |
36 | + def default_model | |
37 | + Artist | |
38 | + end | |
39 | +end | ... | ... |