Commit b9948a09fd60646e208b94925093b5e023f95c52

Authored by Andrew Kane
1 parent 2c49d184

Added unscope option to better support working with default scopes

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
... ... @@ -10,6 +10,7 @@ module Searchkick
10 10 # legacy
11 11 record_ids ||= min_id..max_id
12 12  
  13 + klass = Searchkick.scope(klass)
13 14 relation = Searchkick.load_records(klass, record_ids)
14 15 relation = relation.search_import if relation.respond_to?(:search_import)
15 16  
... ...
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
... ... @@ -13,6 +13,7 @@ module Searchkick
13 13 {id: parts[0], routing: parts[1]}
14 14 end
15 15  
  16 + klass = Searchkick.scope(klass)
16 17 index.send(:record_indexer).reindex_items(klass, items, method_name: nil)
17 18 end
18 19 end
... ...
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
... ... @@ -309,6 +309,8 @@ module Searchkick
309 309 end
310 310  
311 311 def results_query(records, hits)
  312 + records = Searchkick.scope(records)
  313 +
312 314 ids = hits.map { |hit| hit["_id"] }
313 315 if options[:includes] || options[:model_includes]
314 316 included_relations = []
... ...
test/models/artist.rb 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +class Artist
  2 + searchkick unscope: true
  3 +
  4 + def should_index?
  5 + should_index
  6 + end
  7 +end
... ...
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
... ...
test/unscope_test.rb 0 → 100644
... ... @@ -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
... ...