From 2578da02eec96741dc5fa4276d5bc52aceea0129 Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 7 Oct 2024 15:34:21 +0200
Subject: [PATCH 01/40] chore: update algolia version
---
Gemfile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Gemfile b/Gemfile
index 3352617..6d8c274 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,7 +1,7 @@
source "http://rubygems.org"
gem 'json', '>= 1.5.1'
-gem 'algolia', '< 3.0.0'
+gem 'algolia', '>= 3.0.0'
if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
gem 'rubysl', '~> 2.0', :platform => :rbx
From 9b1c417dc9e358c01ce54ebbf61c84d9e8c6068e Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Wed, 9 Oct 2024 10:49:50 +0200
Subject: [PATCH 02/40] WIP: fix tests until FowardToReplicas
---
Gemfile | 2 +-
lib/algoliasearch-rails.rb | 224 +++++++++++++++++++++--------
lib/algoliasearch/configuration.rb | 3 +-
spec/integration_spec.rb | 151 +++++++++----------
spec/spec_helper.rb | 10 +-
5 files changed, 246 insertions(+), 144 deletions(-)
diff --git a/Gemfile b/Gemfile
index 6d8c274..7226ff4 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,7 +1,7 @@
source "http://rubygems.org"
gem 'json', '>= 1.5.1'
-gem 'algolia', '>= 3.0.0'
+gem 'algolia', '>= 3.4.0'
if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
gem 'rubysl', '~> 2.0', :platform => :rbx
diff --git a/lib/algoliasearch-rails.rb b/lib/algoliasearch-rails.rb
index 82754dc..a225c2c 100644
--- a/lib/algoliasearch-rails.rb
+++ b/lib/algoliasearch-rails.rb
@@ -95,7 +95,6 @@ def initialize(options, &block)
def use_serializer(serializer)
@serializer = serializer
- # instance_variable_set("@serializer", serializer)
end
def attribute(*names, &block)
@@ -240,11 +239,16 @@ def get_setting(name)
instance_variable_get("@#{name}")
end
+ # TODO
def to_settings
+ Algolia::Search::IndexSettings.new(to_hash)
+ end
+
+ def to_hash
settings = {}
OPTIONS.each do |k|
v = get_setting(k)
- settings[k] = v if !v.nil?
+ settings[setting_name(k)] = v if !v.nil?
end
if !@options[:replica]
@@ -256,9 +260,18 @@ def to_settings
end
settings.delete(:replicas) if settings[:replicas].empty?
end
+
settings
end
+ def setting_name(name)
+ name.to_s.gsub(/::/, '/').
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
+ tr("-", "_").
+ downcase
+ end
+
def add_index(index_name, options = {}, &block)
raise ArgumentError.new('Cannot specify additional index on a replica index') if @options[:replica]
raise ArgumentError.new('No block given') if !block_given?
@@ -289,19 +302,20 @@ def additional_indexes
# this class wraps an Algolia::Index object ensuring all raised exceptions
# are correctly logged or thrown depending on the `raise_on_failure` option
+ # TODO
class SafeIndex
def initialize(name, raise_on_failure)
@index = AlgoliaSearch.client.init_index(name)
@raise_on_failure = raise_on_failure.nil? || raise_on_failure
end
- ::Algolia::Search::Index.instance_methods(false).each do |m|
- define_method(m) do |*args, &block|
- SafeIndex.log_or_throw(m, @raise_on_failure) do
- @index.send(m, *args, &block)
- end
- end
- end
+ # ::Algolia::Search::Index.instance_methods(false).each do |m|
+ # define_method(m) do |*args, &block|
+ # SafeIndex.log_or_throw(m, @raise_on_failure) do
+ # @index.send(m, *args, &block)
+ # end
+ # end
+ # end
# special handling of wait_task to handle null task_id
def wait_task(task_id)
@@ -493,11 +507,13 @@ def algolia_without_auto_index_scope
Thread.current["algolia_without_auto_index_scope_for_#{self.model_name}"]
end
+ # TODO
def algolia_reindex!(batch_size = AlgoliaSearch::IndexSettings::DEFAULT_BATCH_SIZE, synchronous = false)
return if algolia_without_auto_index_scope
algolia_configurations.each do |options, settings|
next if algolia_indexing_disabled?(options)
- index = algolia_ensure_init(options, settings)
+ ensure_init_new(options, settings)
+ index_name = algolia_index_name(options)
next if options[:replica]
last_task = nil
@@ -505,7 +521,7 @@ def algolia_reindex!(batch_size = AlgoliaSearch::IndexSettings::DEFAULT_BATCH_SI
if algolia_conditional_index?(options)
# delete non-indexable objects
ids = group.select { |o| !algolia_indexable?(o, options) }.map { |o| algolia_object_id_of(o, options) }
- index.delete_objects(ids.select { |id| !id.blank? })
+ AlgoliaSearch.client.delete_objects(index_name, ids.select { |id| !id.blank? })
# select only indexable objects
group = group.select { |o| algolia_indexable?(o, options) }
end
@@ -516,13 +532,14 @@ def algolia_reindex!(batch_size = AlgoliaSearch::IndexSettings::DEFAULT_BATCH_SI
end
attributes.merge 'objectID' => algolia_object_id_of(o, options)
end
- last_task = index.save_objects(objects)
+ last_task = AlgoliaSearch.client.save_objects(index_name, objects).last.task_id
end
- index.wait_task(last_task.raw_response["taskID"]) if last_task and (synchronous || options[:synchronous])
+ AlgoliaSearch.client.wait_for_task(index_name, last_task) if last_task and (synchronous || options[:synchronous])
end
nil
end
+ # TODO
# reindex whole database using a extra temporary index + move operation
def algolia_reindex(batch_size = AlgoliaSearch::IndexSettings::DEFAULT_BATCH_SIZE, synchronous = false)
return if algolia_without_auto_index_scope
@@ -530,28 +547,31 @@ def algolia_reindex(batch_size = AlgoliaSearch::IndexSettings::DEFAULT_BATCH_SIZ
next if algolia_indexing_disabled?(options)
next if options[:replica]
+ ensure_init_new(options, settings)
+ index_name = algolia_index_name(options)
+
# fetch the master settings
- master_index = algolia_ensure_init(options, settings)
- master_settings = master_index.get_settings rescue {} # if master doesn't exist yet
+
+ master_settings = AlgoliaSearch.client.get_settings(index_name).to_hash rescue {} # if master doesn't exist yet
master_exists = master_settings != {}
- master_settings.merge!(JSON.parse(settings.to_settings.to_json)) # convert symbols to strings
+ master_settings.merge!(settings.to_hash)
# remove the replicas of the temporary index
master_settings.delete :replicas
master_settings.delete 'replicas'
# init temporary index
- src_index_name = algolia_index_name(options)
- tmp_index_name = "#{src_index_name}.tmp"
+ tmp_index_name = "#{index_name}.tmp"
tmp_options = options.merge({ :index_name => tmp_index_name })
tmp_options.delete(:per_environment) # already included in the temporary index_name
tmp_settings = settings.dup
if options[:check_settings] == false && master_exists
- AlgoliaSearch.client.copy_index!(src_index_name, tmp_index_name, { scope: %w[settings synonyms rules] })
- tmp_index = SafeIndex.new(tmp_index_name, !!options[:raise_on_failure])
- else
- tmp_index = algolia_ensure_init(tmp_options, tmp_settings, master_settings)
+ task_id = AlgoliaSearch.client.operation_index(
+ index_name,
+ Algolia::Search::OperationIndexParams.new(operation: "copy", destination: tmp_index_name, scope: %w[settings synonyms rules])
+ ).task_id
+ AlgoliaSearch.client.wait_for_task(index_name, task_id)
end
algolia_find_in_batches(batch_size) do |group|
@@ -560,15 +580,20 @@ def algolia_reindex(batch_size = AlgoliaSearch::IndexSettings::DEFAULT_BATCH_SIZ
group = group.select { |o| algolia_indexable?(o, tmp_options) }
end
objects = group.map { |o| tmp_settings.get_attributes(o).merge 'objectID' => algolia_object_id_of(o, tmp_options) }
- tmp_index.save_objects(objects)
+
+ AlgoliaSearch.client.save_objects(tmp_index_name, objects)
end
- move_task = SafeIndex.move_index(tmp_index.name, src_index_name)
- master_index.wait_task(move_task.raw_response["taskID"]) if synchronous || options[:synchronous]
+ task_id = AlgoliaSearch.client.operation_index(
+ tmp_index_name,
+ Algolia::Search::OperationIndexParams.new(operation: "move", destination: index_name)
+ ).task_id
+ AlgoliaSearch.client.wait_for_task(index_name, task_id) if synchronous || options[:synchronous]
end
nil
end
+ # TODO
def algolia_set_settings(synchronous = false)
algolia_configurations.each do |options, settings|
if options[:primary_settings] && options[:inherit]
@@ -586,77 +611,94 @@ def algolia_set_settings(synchronous = false)
end
end
+ # TODO
def algolia_index_objects(objects, synchronous = false)
algolia_configurations.each do |options, settings|
next if algolia_indexing_disabled?(options)
- index = algolia_ensure_init(options, settings)
+ ensure_init_new(options, settings)
+ index_name = algolia_index_name(options)
+
next if options[:replica]
- task = index.save_objects(objects.map { |o| settings.get_attributes(o).merge 'objectID' => algolia_object_id_of(o, options) })
- index.wait_task(task.raw_response["taskID"]) if synchronous || options[:synchronous]
+ tasks = AlgoliaSearch.client.save_objects(index_name, objects.map { |o| settings.get_attributes(o).merge 'objectID' => algolia_object_id_of(o, options) })
+ tasks.each do |task|
+ AlgoliaSearch.client.wait_for_task(index_name, task.task_id) if synchronous || options[:synchronous]
+ end
end
end
+ # TODO
def algolia_index!(object, synchronous = false)
return if algolia_without_auto_index_scope
algolia_configurations.each do |options, settings|
next if algolia_indexing_disabled?(options)
+
object_id = algolia_object_id_of(object, options)
- index = algolia_ensure_init(options, settings)
+ index_name = algolia_index_name(options)
+ ensure_init_new(options, settings)
next if options[:replica]
+
if algolia_indexable?(object, options)
raise ArgumentError.new("Cannot index a record with a blank objectID") if object_id.blank?
+ resp = AlgoliaSearch.client.save_object(index_name, settings.get_attributes(object).merge({ 'objectID' => algolia_object_id_of(object, options) }))
if synchronous || options[:synchronous]
- index.save_object!(settings.get_attributes(object).merge 'objectID' => algolia_object_id_of(object, options))
- else
- index.save_object(settings.get_attributes(object).merge 'objectID' => algolia_object_id_of(object, options))
+ AlgoliaSearch.client.wait_for_task(index_name, resp.task_id)
end
elsif algolia_conditional_index?(options) && !object_id.blank?
# remove non-indexable objects
+ resp = AlgoliaSearch.client.delete_object(index_name, object_id)
if synchronous || options[:synchronous]
- index.delete_object!(object_id)
- else
- index.delete_object(object_id)
+ AlgoliaSearch.client.wait_for_task(index_name, resp.task_id)
end
end
end
nil
end
+ # TODO
def algolia_remove_from_index!(object, synchronous = false)
return if algolia_without_auto_index_scope
object_id = algolia_object_id_of(object)
raise ArgumentError.new("Cannot index a record with a blank objectID") if object_id.blank?
algolia_configurations.each do |options, settings|
next if algolia_indexing_disabled?(options)
- index = algolia_ensure_init(options, settings)
+ ensure_init_new(options, settings)
+ index_name = algolia_index_name(options)
+
next if options[:replica]
+
+ resp = AlgoliaSearch.client.delete_object(index_name, object_id)
if synchronous || options[:synchronous]
- index.delete_object!(object_id)
- else
- index.delete_object(object_id)
+ AlgoliaSearch.client.wait_for_task(index_name, resp.task_id)
end
end
nil
end
+ # TODO
def algolia_clear_index!(synchronous = false)
algolia_configurations.each do |options, settings|
- next if algolia_indexing_disabled?(options)
- index = algolia_ensure_init(options, settings)
- next if options[:replica]
- synchronous || options[:synchronous] ? index.clear_objects! : index.clear_objects
- @algolia_indexes[settings] = nil
+ next if algolia_indexing_disabled?(options) || options[:replica]
+
+ ensure_init_new(options, settings)
+ index_name = algolia_index_name(options)
+ res = AlgoliaSearch.client.clear_objects(index_name)
+
+ if synchronous || options[:synchronous]
+ AlgoliaSearch.client.wait_for_task(index_name, res.task_id)
+ end
end
nil
end
+ # TODO
+
def algolia_raw_search(q, params = {})
- index_name = params.delete(:index) ||
+ index_name_base = params.delete(:index) ||
params.delete('index') ||
params.delete(:replica) ||
params.delete('replica')
- index = algolia_index(index_name)
- index.search(q, Hash[params.map { |k,v| [k.to_s, v.to_s] }])
+ index_name = algolia_index_name(algoliasearch_options, index_name_base)
+ AlgoliaSearch.client.search_single_index(index_name,Hash[params.to_h.map { |k,v| [k.to_s, v.to_s] }].merge({query: q})).to_hash
end
module AdditionalMethods
@@ -672,7 +714,7 @@ def algolia_raw_answer
end
def algolia_facets
- @algolia_json['facets']
+ @algolia_json[:facets]
end
private
@@ -681,6 +723,7 @@ def algolia_init_raw_answer(json)
end
end
+ # TODO
def algolia_search(q, params = {})
if AlgoliaSearch.configuration[:pagination_backend]
# kaminari, will_paginate, and pagy start pagination at 1, Algolia starts at 0
@@ -688,7 +731,7 @@ def algolia_search(q, params = {})
params[:page] -= 1 if params[:page].to_i > 0
end
json = algolia_raw_search(q, params)
- hit_ids = json['hits'].map { |hit| hit['objectID'] }
+ hit_ids = json[:hits].map { |hit| hit[:objectID] }
if defined?(::Mongoid::Document) && self.include?(::Mongoid::Document)
condition_key = algolia_object_id_method.in
else
@@ -697,36 +740,39 @@ def algolia_search(q, params = {})
results_by_id = algoliasearch_options[:type].where(condition_key => hit_ids).index_by do |hit|
algolia_object_id_of(hit)
end
- results = json['hits'].map do |hit|
- o = results_by_id[hit['objectID'].to_s]
+ results = json[:hits].map do |hit|
+ o = results_by_id[hit[:objectID].to_s]
if o
- o.highlight_result = hit['_highlightResult']
- o.snippet_result = hit['_snippetResult']
+ o.highlight_result = hit[:_highlightResult]
+ o.snippet_result = hit[:_snippetResult]
o
end
end.compact
# Algolia has a default limit of 1000 retrievable hits
- total_hits = json['nbHits'].to_i < json['nbPages'].to_i * json['hitsPerPage'].to_i ?
- json['nbHits'].to_i: json['nbPages'].to_i * json['hitsPerPage'].to_i
- res = AlgoliaSearch::Pagination.create(results, total_hits, algoliasearch_options.merge({ :page => json['page'].to_i + 1, :per_page => json['hitsPerPage'] }))
+ total_hits = json[:nbHits].to_i < json[:nbPages].to_i * json[:hitsPerPage].to_i ?
+ json[:nbHits].to_i: json[:nbPages].to_i * json[:hitsPerPage].to_i
+ res = AlgoliaSearch::Pagination.create(results, total_hits, algoliasearch_options.merge({ :page => json[:page].to_i + 1, :per_page => json[:hitsPerPage] }))
res.extend(AdditionalMethods)
res.send(:algolia_init_raw_answer, json)
res
end
+ # TODO
def algolia_search_for_facet_values(facet, text, params = {})
index_name = params.delete(:index) ||
params.delete('index') ||
params.delete(:replica) ||
params.delete('replicas')
- index = algolia_index(index_name)
- query = Hash[params.map { |k, v| [k.to_s, v.to_s] }]
- index.search_for_facet_values(facet, text, query)['facetHits']
+ index_name ||= algolia_index_name(algoliasearch_options)
+ req = Algolia::Search::SearchForFacetValuesRequest.new({facet_query: text, params: params.to_query})
+
+ AlgoliaSearch.client.search_for_facet_values(index_name, facet, req).facet_hits
end
# deprecated (renaming)
alias :algolia_search_facet :algolia_search_for_facet_values
+ # TODO
def algolia_index(name = nil)
if name
algolia_configurations.each do |o, s|
@@ -737,9 +783,19 @@ def algolia_index(name = nil)
algolia_ensure_init
end
- def algolia_index_name(options = nil)
+ def ensure_algolia_index(name = nil)
+ if name
+ algolia_configurations.each do |o, s|
+ return ensure_init_new(o, s) if o[:index_name].to_s == name.to_s
+ end
+ raise ArgumentError.new("Invalid index/replica name: #{name}")
+ end
+ ensure_init_new
+ end
+
+ def algolia_index_name(options = nil, index_name = nil)
options ||= algoliasearch_options
- name = options[:index_name] || model_name.to_s.gsub('::', '_')
+ name = index_name || options[:index_name] || model_name.to_s.gsub('::', '_')
name = "#{name}_#{Rails.env.to_s}" if options[:per_environment]
name
end
@@ -774,6 +830,7 @@ def algolia_must_reindex?(object)
protected
+ # TODO - deprecate
def algolia_ensure_init(options = nil, settings = nil, index_settings = nil)
raise ArgumentError.new('No `algoliasearch` block found in your model.') if algoliasearch_settings.nil?
@@ -806,8 +863,51 @@ def algolia_ensure_init(options = nil, settings = nil, index_settings = nil)
@algolia_indexes[settings]
end
+ def ensure_init_new(options = nil, settings = nil, index_settings_hash = nil)
+ raise ArgumentError.new('No `algoliasearch` block found in your model.') if algoliasearch_settings.nil?
+
+ @algolia_indexes_init ||= {}
+
+ options ||= algoliasearch_options
+ settings ||= algoliasearch_settings
+
+ return if @algolia_indexes_init[settings]
+
+ index_name = algolia_index_name(options)
+
+
+ index_settings_hash ||= settings.to_settings.to_hash
+ index_settings_hash = options[:primary_settings].to_settings.to_hash.merge(index_settings_hash) if options[:inherit]
+ replicas = index_settings_hash.delete(:replicas) || index_settings_hash.delete('replicas')
+ index_settings_hash[:replicas] = replicas unless replicas.nil? || options[:inherit]
+
+ options[:check_settings] = true if options[:check_settings].nil?
+
+ current_settings = if options[:check_settings] && !algolia_indexing_disabled?(options)
+ AlgoliaSearch.client.get_settings(index_name, {:getVersion => 1}).to_hash rescue nil # if the index doesn't exist
+ end
+
+ if !algolia_indexing_disabled?(options) && options[:check_settings] && algoliasearch_settings_changed?(current_settings, index_settings_hash)
+ s = index_settings_hash.map do |k, v|
+ [settings.setting_name(k), v]
+ end.to_h
+
+ synonyms = s.delete("synonyms") || s.delete(:synonyms)
+ unless synonyms.nil? || synonyms.empty?
+ resp = AlgoliaSearch.client.save_synonyms(index_name,synonyms.map {|s| Algolia::Search::SynonymHit.new({object_id: s.join("-"), synonyms: s, type: "synonym"}) } )
+ AlgoliaSearch.client.wait_for_task(index_name, resp.task_id) if options[:synchronous]
+ end
+
+ resp = AlgoliaSearch.client.set_settings(index_name, Algolia::Search::IndexSettings.new(s))
+ AlgoliaSearch.client.wait_for_task(index_name, resp.task_id) if options[:synchronous]
+ end
+
+ return
+ end
+
private
+ # TODO
def algolia_configurations
raise ArgumentError.new('No `algoliasearch` block found in your model.') if algoliasearch_settings.nil?
if @configurations.nil?
@@ -843,7 +943,7 @@ def algolia_object_id_changed?(o, options = nil)
def algoliasearch_settings_changed?(prev, current)
return true if prev.nil?
current.each do |k, v|
- prev_v = prev[k.to_s]
+ prev_v = prev[k.to_sym]
if v.is_a?(Array) and prev_v.is_a?(Array)
# compare array of strings, avoiding symbols VS strings comparison
return true if v.map { |x| x.to_s } != prev_v.map { |x| x.to_s }
diff --git a/lib/algoliasearch/configuration.rb b/lib/algoliasearch/configuration.rb
index cd48b49..3b6bda3 100644
--- a/lib/algoliasearch/configuration.rb
+++ b/lib/algoliasearch/configuration.rb
@@ -37,8 +37,9 @@ def client
@client
end
+ # TODO
def setup_client
- @client = Algolia::Search::Client.new(Algolia::Search::Config.new(@@configuration), client_opts)
+ @client = Algolia::SearchClient.create(@@configuration[:application_id], @@configuration[:api_key])
end
def default_configuration
diff --git a/spec/integration_spec.rb b/spec/integration_spec.rb
index 18a71a4..7beadf2 100644
--- a/spec/integration_spec.rb
+++ b/spec/integration_spec.rb
@@ -294,8 +294,9 @@ def nb_children
end
# create this index before the class actually loads, to ensure the customRanking is updated
-index = AlgoliaSearch.client.init_index(safe_index_name('City_replica2'))
-index.set_settings!({'customRanking' => ['desc(d)']})
+index_name = safe_index_name('City_replica2')
+res = AlgoliaSearch.client.set_settings(index_name, Algolia::Search::IndexSettings.new(custom_ranking: ['desc(d)']))
+AlgoliaSearch.client.wait_for_task(index_name, res.task_id)
class City < ActiveRecord::Base
include AlgoliaSearch
@@ -313,12 +314,12 @@ def geoloc_array
add_attribute :a_null_lat, :a_lng
customRanking ['desc(b)']
- add_replica safe_index_name('City_replica1'), :per_environment => true do
+ add_replica safe_index_name('City_replica1'), :per_environment => true, :synchronous => true do
searchableAttributes ['country']
customRanking ['asc(a)']
end
- add_replica safe_index_name('City_replica2'), :per_environment => true do
+ add_replica safe_index_name('City_replica2'), :per_environment => true, :synchronous => true do
customRanking ['asc(a)', 'desc(c)']
end
end
@@ -364,8 +365,8 @@ def public?
describe 'DisabledIndexing' do
it 'should not call get_settings' do
- expect_any_instance_of(Algolia::Search::Index).not_to receive(:get_settings)
- DisabledIndexing.send(:algolia_ensure_init)
+ expect_any_instance_of(Algolia::SearchClient).not_to receive(:get_settings)
+ DisabledIndexing.send(:ensure_init_new)
end
end
@@ -373,7 +374,7 @@ def public?
before(:each) do
# NOTE:
# Redefine below class *each* time to avoid the cache in the class.
- # If the cahce is ready, algolia_ensure_init call neither set_settings nor set_settings! ever.
+ # If the cache is ready, algolia_ensure_init call neither set_settings nor set_settings! ever.
Object.send(:remove_const, :EnableCheckSettingsSynchronously) if Object.constants.include?(:EnableCheckSettingsSynchronously)
class EnableCheckSettingsSynchronously < ActiveRecord::Base
include AlgoliaSearch
@@ -389,9 +390,9 @@ class EnableCheckSettingsSynchronously < ActiveRecord::Base
end
it 'should call set_setting with wait_task(sync)' do
- expect_any_instance_of(Algolia::Search::Index).to receive(:set_settings).and_call_original # wait_task use this return val
- expect_any_instance_of(Algolia::Search::Index).to receive(:wait_task)
- EnableCheckSettingsSynchronously.send(:algolia_ensure_init)
+ expect_any_instance_of(Algolia::SearchClient).to receive(:set_settings).and_call_original # wait_task use this return val
+ expect_any_instance_of(Algolia::SearchClient).to receive(:wait_for_task)
+ EnableCheckSettingsSynchronously.send(:ensure_init_new)
end
end
@@ -401,8 +402,8 @@ class EnableCheckSettingsSynchronously < ActiveRecord::Base
end
it 'should not call set_setting' do
- expect_any_instance_of(Algolia::Search::Index).not_to receive(:set_settings)
- EnableCheckSettingsSynchronously.send(:algolia_ensure_init)
+ expect_any_instance_of(Algolia::SearchClient).not_to receive(:set_settings)
+ EnableCheckSettingsSynchronously.send(:ensure_init_new)
end
end
end
@@ -411,7 +412,7 @@ class EnableCheckSettingsSynchronously < ActiveRecord::Base
before(:each) do
# NOTE:
# Redefine below class *each* time to avoid the cache in the class.
- # If the cahce is ready, algolia_ensure_init call neither set_settings nor set_settings! ever.
+ # If the cache is ready, algolia_ensure_init call neither set_settings nor set_settings! ever.
Object.send(:remove_const, :EnableCheckSettingsAsynchronously) if Object.constants.include?(:EnableCheckSettingsAsynchronously)
class EnableCheckSettingsAsynchronously < ActiveRecord::Base
include AlgoliaSearch
@@ -427,9 +428,9 @@ class EnableCheckSettingsAsynchronously < ActiveRecord::Base
end
it 'should call set_setting without wait_task(sync)' do
- expect_any_instance_of(Algolia::Search::Index).to receive(:set_settings)
- expect_any_instance_of(Algolia::Search::Index).not_to receive(:wait_task)
- EnableCheckSettingsAsynchronously.send(:algolia_ensure_init)
+ expect_any_instance_of(Algolia::SearchClient).to receive(:set_settings)
+ expect_any_instance_of(Algolia::SearchClient).not_to receive(:wait_for_task)
+ EnableCheckSettingsAsynchronously.send(:ensure_init_new)
end
end
@@ -439,8 +440,8 @@ class EnableCheckSettingsAsynchronously < ActiveRecord::Base
end
it 'should not call set_setting' do
- expect_any_instance_of(Algolia::Search::Index).not_to receive(:set_settings)
- EnableCheckSettingsAsynchronously.send(:algolia_ensure_init)
+ expect_any_instance_of(Algolia::SearchClient).not_to receive(:set_settings)
+ EnableCheckSettingsAsynchronously.send(:ensure_init_new)
end
end
end
@@ -451,8 +452,8 @@ class EnableCheckSettingsAsynchronously < ActiveRecord::Base
end
it 'should call get_settings' do
- expect_any_instance_of(Algolia::Search::Index).to receive(:get_settings)
- SequelBook.send(:algolia_ensure_init)
+ expect_any_instance_of(Algolia::SearchClient).to receive(:get_settings)
+ SequelBook.send(:ensure_init_new)
end
it "should index the book" do
@@ -658,8 +659,8 @@ class SerializedObject < ActiveRecord::Base
it "should convert to utf-8" do
EncodedString.create!
results = EncodedString.raw_search ''
- expect(results['hits'].size).to eq(1)
- expect(results['hits'].first['value']).to eq("\xC2\xA0\xE2\x80\xA2\xC2\xA0".force_encoding('utf-8'))
+ expect(results[:hits].size).to eq(1)
+ expect(results[:hits].first[:value]).to eq("\xC2\xA0\xE2\x80\xA2\xC2\xA0".force_encoding('utf-8'))
end
end
end
@@ -768,7 +769,7 @@ class SerializedObject < ActiveRecord::Base
describe 'Namespaced::Model' do
before(:all) do
- Namespaced::Model.index.clear_objects!
+ Namespaced::Model.clear_index!(true)
end
it "should have an index name without :: hierarchy" do
@@ -825,11 +826,14 @@ class SerializedObject < ActiveRecord::Base
@i1.children << NestedItem.create(:hidden => true) << NestedItem.create(:hidden => true)
NestedItem.where(:id => [@i1.id, @i2.id]).reindex!(AlgoliaSearch::IndexSettings::DEFAULT_BATCH_SIZE, true)
- result = NestedItem.index.get_object(@i1.id)
- result['nb_children'].should == 2
+ # result = AlgoliaSearch.client.get_object(NestedItem.index_name, @i1.id) # TODO: should be bugfixed and should replace the line below
+ result = AlgoliaSearch.client.get_objects(Algolia::Search::GetObjectsParams.new(
+ requests: [Algolia::Search::GetObjectsRequest.new(object_id: 'objectID1', index_name: 'my_index')]
+ )).results.first
+ result[:nb_children].should == 2
result = NestedItem.raw_search('')
- result['nbHits'].should == 1
+ result[:nbHits].should == 1
if @i2.respond_to? :update_attributes
@i2.update_attributes :hidden => false
@@ -838,7 +842,7 @@ class SerializedObject < ActiveRecord::Base
end
result = NestedItem.raw_search('')
- result['nbHits'].should == 2
+ result[:nbHits].should == 2
end
end
@@ -870,8 +874,8 @@ class SerializedObject < ActiveRecord::Base
it "should be raw searchable" do
results = Color.raw_search("blue")
- results['hits'].size.should eq(1)
- results['nbHits'].should eq(1)
+ results[:hits].size.should eq(1)
+ results[:nbHits].should eq(1)
end
it "should not auto index if scoped" do
@@ -940,7 +944,7 @@ class SerializedObject < ActiveRecord::Base
it "should index an array of objects" do
json = Color.raw_search('')
Color.index_objects Color.limit(1), true # reindex last color, `limit` is incompatible with the reindex! method
- json['nbHits'].should eq(Color.raw_search('')['nbHits'])
+ json[:nbHits].should eq(Color.raw_search('')[:nbHits])
end
it "should not index non-saved object" do
@@ -956,11 +960,11 @@ class SerializedObject < ActiveRecord::Base
@blue = Color.create!(:name => "blue", :short_name => "blu", :hex => 0x0000FF)
@black = Color.create!(:name => "black", :short_name => "bla", :hex => 0x000000)
@green = Color.create!(:name => "green", :short_name => "gre", :hex => 0x00FF00)
- facets = Color.search_for_facet_values('short_name', 'bl', :query => 'black')
+ facets = Color.search_for_facet_values('short_name', 'bl', { :query => 'black' })
expect(facets.size).to eq(1)
- expect(facets.first['value']).to eq('bla')
- expect(facets.first['highlighted']).to eq('bla')
- expect(facets.first['count']).to eq(1)
+ expect(facets.first.value).to eq('bla')
+ expect(facets.first.highlighted).to eq('bla')
+ expect(facets.first.count).to eq(1)
end
end
@@ -1168,18 +1172,18 @@ class SerializedObject < ActiveRecord::Base
end
it "should be searchable using replica index" do
- r = City.index(safe_index_name('City_replica1')).search 'no land'
- r['nbHits'].should eq(1)
+ r = AlgoliaSearch.client.search_single_index(safe_index_name("City_replica1_#{Rails.env.to_s}"), { query: 'no land' })
+ r.nb_hits.should eq(1)
end
it "should be searchable using replica index 2" do
r = City.raw_search 'no land', :index => safe_index_name('City_replica1')
- r['nbHits'].should eq(1)
+ r[:nbHits].should eq(1)
end
it "should be searchable using replica index 3" do
r = City.raw_search 'no land', :replica => safe_index_name('City_replica1')
- r['nbHits'].should eq(1)
+ r[:nbHits].should eq(1)
end
it "should be searchable using replica index 4" do
@@ -1194,37 +1198,32 @@ class SerializedObject < ActiveRecord::Base
it "should reindex with replicas in place" do
City.reindex!(AlgoliaSearch::IndexSettings::DEFAULT_BATCH_SIZE, true)
- expect(City.index.get_settings['replicas'].length).to eq(2)
+ expect(AlgoliaSearch.client.get_settings(City.index_name).replicas.length).to eq(2)
end
it "should reindex with replicas using a temporary index" do
City.reindex(AlgoliaSearch::IndexSettings::DEFAULT_BATCH_SIZE, true)
- expect(City.index.get_settings['replicas'].length).to eq(2)
+ expect(AlgoliaSearch.client.get_settings(City.index_name).replicas.length).to eq(2)
end
it "should not include the replicas setting on replicas" do
City.send(:algolia_configurations).to_a.each do |v|
if v[0][:replica]
- expect(v[1].to_settings[:replicas]).to be_nil
+ expect(v[1].to_settings.replicas).to be_nil
else
- expect(v[1].to_settings[:replicas]).to match_array(["#{safe_index_name('City_replica1')}_#{Rails.env}", "#{safe_index_name('City_replica2')}_#{Rails.env}"])
+ expect(v[1].to_settings.replicas).to match_array(["#{safe_index_name('City_replica1')}_#{Rails.env}", "#{safe_index_name('City_replica2')}_#{Rails.env}"])
end
end
end
- it "should browse" do
- total = City.index.search('')['nbHits']
- n = 0
- City.index.browse_objects do |hit|
- n += 1
- end
- expect(n).to eq(total)
- end
-
it "should have set the custom ranking on all indices" do
- expect(City.index.get_settings['customRanking']).to eq(['desc(b)'])
- expect(City.index(safe_index_name('City_replica1')).get_settings['customRanking']).to eq(['asc(a)'])
- expect(City.index(safe_index_name('City_replica2')).get_settings['customRanking']).to eq(['asc(a)', 'desc(c)'])
+ City.ensure_algolia_index
+ City.ensure_algolia_index(safe_index_name("City_replica1"))
+ City.ensure_algolia_index(safe_index_name("City_replica2"))
+
+ expect(AlgoliaSearch.client.get_settings(City.index_name).custom_ranking).to eq(['desc(b)'])
+ expect(AlgoliaSearch.client.get_settings(City.index_name(nil, safe_index_name("City_replica1"))).custom_ranking).to eq(['asc(a)'])
+ expect(AlgoliaSearch.client.get_settings(City.index_name(nil, safe_index_name("City_replica2"))).custom_ranking).to eq(['asc(a)', 'desc(c)'])
end
end
@@ -1253,23 +1252,26 @@ class ForwardToReplicas < ActiveRecord::Base
end
after(:each) do
- ForwardToReplicas.index.delete!
+ res = AlgoliaSearch.client.delete_index(ForwardToReplicas.index_name)
+ AlgoliaSearch.client.wait_for_task(ForwardToReplicas.index_name, res.task_id)
end
it 'shouldn\'t have inherited from the primary' do
- ForwardToReplicas.send :algolia_ensure_init
+ ForwardToReplicas.send :ensure_init_new
# Hacky way to have a wait on set_settings
ForwardToReplicas.create(:name => 'val')
ForwardToReplicas.reindex!
- primary_settings = ForwardToReplicas.index.get_settings
- expect(primary_settings['searchableAttributes']).to eq(%w(first_value))
- expect(primary_settings['attributesToHighlight']).to eq(%w(primary_highlight))
- replica_settings = ForwardToReplicas.index(safe_index_name('ForwardToReplicas_replica')).get_settings
- expect(replica_settings['searchableAttributes']).to eq(nil)
- expect(replica_settings['attributesToHighlight']).to eq(%w(replica_highlight))
+
+ primary_settings = AlgoliaSearch.client.get_settings(ForwardToReplicas.index_name)
+ expect(primary_settings.searchable_attributes).to eq(%w(first_value))
+ expect(primary_settings.attributes_to_highlight).to eq(%w(primary_highlight))
+
+ replica_settings = AlgoliaSearch.client.get_settings(ForwardToReplicas.index_name(nil, safe_index_name('ForwardToReplicas_replica')))
+ expect(replica_settings.searchable_attributes).to eq(nil)
+ expect(replica_settings.attributes_to_highlight).to eq(%w(replica_highlight))
end
it 'should update the replica settings when changed' do
@@ -1293,23 +1295,23 @@ class ForwardToReplicasTwo < ActiveRecord::Base
end
end
- ForwardToReplicas.send :algolia_ensure_init
+ ForwardToReplicas.send :ensure_init_new
- ForwardToReplicasTwo.send :algolia_ensure_init
+ ForwardToReplicasTwo.send :ensure_init_new
# Hacky way to have a wait on set_settings
ForwardToReplicasTwo.create(:name => 'val')
ForwardToReplicasTwo.reindex!
- primary_settings = ForwardToReplicas.index.get_settings
- expect(primary_settings['searchableAttributes']).to eq(%w(second_value))
- expect(primary_settings['attributesToHighlight']).to eq(%w(primary_highlight))
+ primary_settings = AlgoliaSearch.client.get_settings(ForwardToReplicas.index_name)
+ expect(primary_settings.searchable_attributes).to eq(%w(second_value))
+ expect(primary_settings.attributes_to_highlight).to eq(%w(primary_highlight))
- replica_settings = ForwardToReplicas.index(safe_index_name('ForwardToReplicas_replica')).get_settings
- expect(replica_settings['searchableAttributes']).to eq(%w(second_value))
- expect(replica_settings['attributesToHighlight']).to eq(%w(replica_highlight))
+ replica_settings = AlgoliaSearch.client.get_settings(ForwardToReplicas.index_name(nil, safe_index_name('ForwardToReplicas_replica')))
+ expect(replica_settings.searchable_attributes).to eq(%w(second_value))
+ expect(replica_settings.attributes_to_highlight).to eq(%w(replica_highlight))
- expect(ForwardToReplicas.index.name).to eq(ForwardToReplicasTwo.index.name)
+ expect(ForwardToReplicas.index_name).to eq(ForwardToReplicasTwo.index_name)
end
it "shouldn't update the replica settings if there is no change" do
@@ -1333,15 +1335,15 @@ class ForwardToReplicasTwo < ActiveRecord::Base
end
end
- ForwardToReplicas.send :algolia_ensure_init
+ ForwardToReplicas.send :ensure_init_new
# Hacky way to hook replica settings update
ForwardToReplicas.create(:name => 'val')
ForwardToReplicas.reindex!
- expect_any_instance_of(Algolia::Search::Index).not_to receive(:set_settings!)
+ expect_any_instance_of(Algolia::SearchClient).not_to receive(:set_settings)
- ForwardToReplicasTwo.send :algolia_ensure_init
+ ForwardToReplicasTwo.send :ensure_init_new
# Hacky way to hook replica settings update
ForwardToReplicasTwo.create(:name => 'val2')
@@ -1542,7 +1544,6 @@ class ForwardToReplicasTwo < ActiveRecord::Base
end
end
-
describe 'Disabled' do
before(:all) do
DisabledBoolean.index.clear_objects!
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index f8e6f4a..8860569 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -32,8 +32,8 @@
# Remove all indexes setup in this run in local or CI
c.after(:suite) do
safe_index_list.each do |i|
- index = AlgoliaSearch.client.init_index(i['name'])
- index.delete!
+ res = AlgoliaSearch.client.delete_index(i.name)
+ AlgoliaSearch.client.wait_for_task(i.name, res.task_id)
end
end
end
@@ -48,7 +48,7 @@ def safe_index_name(name)
# get a list of safe indexes in local or CI
def safe_index_list
- list = AlgoliaSearch.client.list_indexes['items']
- list = list.select { |index| index["name"].include?(SAFE_INDEX_PREFIX) }
- list.sort_by { |index| index["primary"] || "" }
+ list = AlgoliaSearch.client.list_indices.items
+ list = list.select { |index| index.name.include?(SAFE_INDEX_PREFIX) }
+ list.sort_by { |index| index.primary || "" }
end
From bc80b19726f4a95027df83f07759ce3aff94ad2d Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Wed, 9 Oct 2024 11:07:07 +0200
Subject: [PATCH 03/40] chore: fix SubReplicas tests
---
lib/algoliasearch-rails.rb | 13 ++++++++++++-
spec/integration_spec.rb | 4 ++--
2 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/lib/algoliasearch-rails.rb b/lib/algoliasearch-rails.rb
index a225c2c..7197ba6 100644
--- a/lib/algoliasearch-rails.rb
+++ b/lib/algoliasearch-rails.rb
@@ -697,7 +697,18 @@ def algolia_raw_search(q, params = {})
params.delete('index') ||
params.delete(:replica) ||
params.delete('replica')
- index_name = algolia_index_name(algoliasearch_options, index_name_base)
+
+ opts = algoliasearch_options
+ unless index_name_base.nil?
+ algolia_configurations.each do |o, s|
+ if o[:index_name].to_s == index_name_base.to_s
+ opts = o
+ ensure_algolia_index(index_name_base)
+ end
+ end
+ end
+
+ index_name = algolia_index_name(opts, index_name_base)
AlgoliaSearch.client.search_single_index(index_name,Hash[params.to_h.map { |k,v| [k.to_s, v.to_s] }].merge({query: q})).to_hash
end
diff --git a/spec/integration_spec.rb b/spec/integration_spec.rb
index 7beadf2..6434829 100644
--- a/spec/integration_spec.rb
+++ b/spec/integration_spec.rb
@@ -542,11 +542,11 @@ class SubReplicas < ActiveRecord::Base
searchableAttributes ['name']
customRanking ["asc(name)"]
- add_index safe_index_name("Additional_Index"), :per_environment => true do
+ add_index safe_index_name("Additional_Index"), :per_environment => true, :synchronous => true do
searchableAttributes ['name']
customRanking ["asc(name)"]
- add_replica safe_index_name("Replica_Index"), :per_environment => true do
+ add_replica safe_index_name("Replica_Index"), :per_environment => true, :synchronous => true do
searchableAttributes ['name']
customRanking ["desc(name)"]
end
From c32aed4271fc0c511019166d91f2de0921054a5f Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Wed, 9 Oct 2024 11:46:18 +0200
Subject: [PATCH 04/40] chore: fix Book tests
---
spec/integration_spec.rb | 56 +++++++++++++++++++---------------------
1 file changed, 27 insertions(+), 29 deletions(-)
diff --git a/spec/integration_spec.rb b/spec/integration_spec.rb
index 6434829..3e9f994 100644
--- a/spec/integration_spec.rb
+++ b/spec/integration_spec.rb
@@ -1411,8 +1411,11 @@ class ForwardToReplicasTwo < ActiveRecord::Base
describe 'Book' do
before(:all) do
Book.clear_index!(true)
- Book.index(safe_index_name('BookAuthor')).clear_objects
- Book.index(safe_index_name('Book')).clear_objects
+ index_name_author = Book.index_name(nil, safe_index_name('BookAuthor'))
+ index_name_book = Book.index_name(nil, safe_index_name('Book'))
+
+ AlgoliaSearch.client.wait_for_task(index_name_author, AlgoliaSearch.client.clear_objects(index_name_author).task_id)
+ AlgoliaSearch.client.wait_for_task(index_name_book, AlgoliaSearch.client.clear_objects(index_name_book).task_id)
end
it "should index the book in 2 indexes of 3" do
@@ -1421,39 +1424,35 @@ class ForwardToReplicasTwo < ActiveRecord::Base
expect(results.size).to eq(1)
results.should include(@steve_jobs)
- index_author = Book.index(safe_index_name('BookAuthor'))
- index_author.should_not be_nil
- results = index_author.search('steve')
- results['hits'].length.should eq(0)
- results = index_author.search('walter')
- results['hits'].length.should eq(1)
+ results = Book.search("steve", index: safe_index_name('BookAuthor'))
+ results.length.should eq(0)
+ results = Book.search("walter", index: safe_index_name('BookAuthor'))
+ results.length.should eq(1)
# premium -> not part of the public index
- index_book = Book.index(safe_index_name('Book'))
- index_book.should_not be_nil
- results = index_book.search('steve')
- results['hits'].length.should eq(0)
+ results = Book.search("steve", index: safe_index_name('Book'))
+ results.length.should eq(0)
end
it "should sanitize attributes" do
@hack = Book.create! :name => "\"> hack0r", :author => "", :premium => true, :released => true
b = Book.raw_search('hack')
- expect(b['hits'].length).to eq(1)
+ expect(b[:hits].length).to eq(1)
begin
- expect(b['hits'][0]['name']).to eq('"> hack0r')
- expect(b['hits'][0]['author']).to eq('alert(1)')
- expect(b['hits'][0]['_highlightResult']['name']['value']).to eq('"> hack0r')
+ expect(b[:hits][0][:name]).to eq('"> hack0r')
+ expect(b[:hits][0][:author]).to eq('alert(1)')
+ expect(b[:hits][0][:_highlightResult][:name][:value]).to eq('"> hack0r')
rescue
# rails 4.2's sanitizer
begin
- expect(b['hits'][0]['name']).to eq('"> hack0r')
- expect(b['hits'][0]['author']).to eq('')
- expect(b['hits'][0]['_highlightResult']['name']['value']).to eq('"> hack0r')
+ expect(b[:hits][0][:name]).to eq('"> hack0r')
+ expect(b[:hits][0][:author]).to eq('')
+ expect(b[:hits][0][:_highlightResult][:name][:value]).to eq('"> hack0r')
rescue
# jruby
- expect(b['hits'][0]['name']).to eq('"> hack0r')
- expect(b['hits'][0]['author']).to eq('')
- expect(b['hits'][0]['_highlightResult']['name']['value']).to eq('"> hack0r')
+ expect(b[:hits][0][:name]).to eq('"> hack0r')
+ expect(b[:hits][0][:author]).to eq('')
+ expect(b[:hits][0][:_highlightResult][:name][:value]).to eq('"> hack0r')
end
end
end
@@ -1463,9 +1462,8 @@ class ForwardToReplicasTwo < ActiveRecord::Base
book = Book.create! :name => 'Public book', :author => 'me', :premium => false, :released => true
# should be searchable in the 'Book' index
- index = Book.index(safe_index_name('Book'))
- results = index.search('Public book')
- expect(results['hits'].size).to eq(1)
+ results = Book.search("Public book", index: safe_index_name('Book'))
+ expect(results.size).to eq(1)
# update the book and make it non-public anymore (not premium, not released)
if book.respond_to? :update_attributes
@@ -1475,13 +1473,13 @@ class ForwardToReplicasTwo < ActiveRecord::Base
end
# should be removed from the index
- results = index.search('Public book')
- expect(results['hits'].size).to eq(0)
+ results = Book.search("Public book", index: safe_index_name('Book'))
+ expect(results.size).to eq(0)
end
it "should use the per_environment option in the additional index as well" do
- index = Book.index(safe_index_name('Book'))
- expect(index.name).to eq("#{safe_index_name('Book')}_#{Rails.env}")
+ index_name = Book.index_name(nil, safe_index_name('Book'))
+ expect(index_name).to eq("#{safe_index_name('Book')}_#{Rails.env}")
end
end
From 4cc7e77bdc001cfc58192f21badbe7bebbe825bd Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Wed, 9 Oct 2024 11:58:10 +0200
Subject: [PATCH 05/40] chore: fix pagination tests
---
spec/integration_spec.rb | 24 +++++++++++++++++++-----
1 file changed, 19 insertions(+), 5 deletions(-)
diff --git a/spec/integration_spec.rb b/spec/integration_spec.rb
index 3e9f994..2eea1b0 100644
--- a/spec/integration_spec.rb
+++ b/spec/integration_spec.rb
@@ -1487,21 +1487,28 @@ class ForwardToReplicasTwo < ActiveRecord::Base
before(:all) do
require 'kaminari'
AlgoliaSearch.configuration = { :application_id => ENV['ALGOLIA_APPLICATION_ID'], :api_key => ENV['ALGOLIA_API_KEY'], :pagination_backend => :kaminari }
+
+ City.create :name => 'San Francisco', :country => 'USA', :lat => 37.75, :lng => -122.68
+ City.create :name => 'Mountain View', :country => 'No man\'s land', :lat => 37.38, :lng => -122.08
+ end
+
+ after(:all) do
+ City.clear_index!(true)
end
it "should paginate" do
pagination = City.search ''
- pagination.total_count.should eq(City.raw_search('')['nbHits'])
+ pagination.total_count.should eq(City.raw_search('')[:nbHits])
p1 = City.search '', :page => 1, :hitsPerPage => 1
p1.size.should eq(1)
p1[0].should eq(pagination[0])
- p1.total_count.should eq(City.raw_search('')['nbHits'])
+ p1.total_count.should eq(City.raw_search('')[:nbHits])
p2 = City.search '', :page => 2, :hitsPerPage => 1
p2.size.should eq(1)
p2[0].should eq(pagination[1])
- p2.total_count.should eq(City.raw_search('')['nbHits'])
+ p2.total_count.should eq(City.raw_search('')[:nbHits])
end
end
@@ -1509,13 +1516,19 @@ class ForwardToReplicasTwo < ActiveRecord::Base
before(:all) do
require 'will_paginate'
AlgoliaSearch.configuration = { :application_id => ENV['ALGOLIA_APPLICATION_ID'], :api_key => ENV['ALGOLIA_API_KEY'], :pagination_backend => :will_paginate }
+ City.create :name => 'San Francisco', :country => 'USA', :lat => 37.75, :lng => -122.68
+ City.create :name => 'Mountain View', :country => 'No man\'s land', :lat => 37.38, :lng => -122.08
+ end
+
+ after(:all) do
+ City.clear_index!(true)
end
it "should paginate" do
p1 = City.search '', :hitsPerPage => 2
p1.length.should eq(2)
p1.per_page.should eq(2)
- p1.total_entries.should eq(City.raw_search('')['nbHits'])
+ p1.total_entries.should eq(City.raw_search('')[:nbHits])
end
end
@@ -1530,13 +1543,14 @@ class ForwardToReplicasTwo < ActiveRecord::Base
after(:all) do
# Reset the configuration to avoid conflicts with other tests
AlgoliaSearch.configuration = { :application_id => ENV['ALGOLIA_APPLICATION_ID'], :api_key => ENV['ALGOLIA_API_KEY'] }
+ City.clear_index!(true)
end
it "should paginate" do
pagy, cities = City.search '', :hitsPerPage => 2
pagy.page.should eq(1)
pagy.items.should eq(2)
- pagy.count.should eq(City.raw_search('')['nbHits'])
+ pagy.count.should eq(City.raw_search('')[:nbHits])
cities.length.should eq(2)
cities.should be_an(Array)
end
From fb275731f62c24f64767c3df21100b4d963c0586 Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 09:24:33 +0200
Subject: [PATCH 06/40] chore: fix disabled indexing tests
---
spec/integration_spec.rb | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/spec/integration_spec.rb b/spec/integration_spec.rb
index 2eea1b0..01c0f7f 100644
--- a/spec/integration_spec.rb
+++ b/spec/integration_spec.rb
@@ -1558,24 +1558,24 @@ class ForwardToReplicasTwo < ActiveRecord::Base
describe 'Disabled' do
before(:all) do
- DisabledBoolean.index.clear_objects!
- DisabledProc.index.clear_objects!
- DisabledSymbol.index.clear_objects!
+ DisabledBoolean.send(:ensure_init_new)
+ DisabledProc.send(:ensure_init_new)
+ DisabledSymbol.send(:ensure_init_new)
end
it "should disable the indexing using a boolean" do
DisabledBoolean.create :name => 'foo'
- expect(DisabledBoolean.search('').size).to eq(0)
+ expect { DisabledBoolean.search('') }.to raise_error Algolia::AlgoliaHttpError # index doesn't exist
end
it "should disable the indexing using a proc" do
DisabledProc.create :name => 'foo'
- expect(DisabledProc.search('').size).to eq(0)
+ expect { DisabledProc.search('') }.to raise_error Algolia::AlgoliaHttpError # index doesn't exist
end
it "should disable the indexing using a symbol" do
DisabledSymbol.create :name => 'foo'
- expect(DisabledSymbol.search('').size).to eq(0)
+ expect { DisabledSymbol.search('') }.to raise_error Algolia::AlgoliaHttpError # index doesn't exist
end
end
From 8ac022576b6af800dac766942f6f05fd958999db Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 10:02:11 +0200
Subject: [PATCH 07/40] fix tests
---
lib/algoliasearch-rails.rb | 10 ++++++++--
spec/integration_spec.rb | 5 +----
2 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/lib/algoliasearch-rails.rb b/lib/algoliasearch-rails.rb
index 7197ba6..9abd18b 100644
--- a/lib/algoliasearch-rails.rb
+++ b/lib/algoliasearch-rails.rb
@@ -241,7 +241,13 @@ def get_setting(name)
# TODO
def to_settings
- Algolia::Search::IndexSettings.new(to_hash)
+ settings = to_hash
+
+ # Remove the synonyms setting since those need to be set separately
+ settings.delete(:synonyms)
+ settings.delete("synonyms")
+
+ Algolia::Search::IndexSettings.new(settings)
end
def to_hash
@@ -954,7 +960,7 @@ def algolia_object_id_changed?(o, options = nil)
def algoliasearch_settings_changed?(prev, current)
return true if prev.nil?
current.each do |k, v|
- prev_v = prev[k.to_sym]
+ prev_v = prev[k.to_sym] || prev[k.to_s]
if v.is_a?(Array) and prev_v.is_a?(Array)
# compare array of strings, avoiding symbols VS strings comparison
return true if v.map { |x| x.to_s } != prev_v.map { |x| x.to_s }
diff --git a/spec/integration_spec.rb b/spec/integration_spec.rb
index 01c0f7f..bd998bd 100644
--- a/spec/integration_spec.rb
+++ b/spec/integration_spec.rb
@@ -826,10 +826,7 @@ class SerializedObject < ActiveRecord::Base
@i1.children << NestedItem.create(:hidden => true) << NestedItem.create(:hidden => true)
NestedItem.where(:id => [@i1.id, @i2.id]).reindex!(AlgoliaSearch::IndexSettings::DEFAULT_BATCH_SIZE, true)
- # result = AlgoliaSearch.client.get_object(NestedItem.index_name, @i1.id) # TODO: should be bugfixed and should replace the line below
- result = AlgoliaSearch.client.get_objects(Algolia::Search::GetObjectsParams.new(
- requests: [Algolia::Search::GetObjectsRequest.new(object_id: 'objectID1', index_name: 'my_index')]
- )).results.first
+ result = AlgoliaSearch.client.get_object(NestedItem.index_name, @i1.id.to_s)
result[:nb_children].should == 2
result = NestedItem.raw_search('')
From b6ea1a3840e12be07b747dfbab6c23f5eb9ecab1 Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 10:02:23 +0200
Subject: [PATCH 08/40] ensure latest gem version
---
Gemfile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Gemfile b/Gemfile
index 7226ff4..4143eab 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,7 +1,7 @@
source "http://rubygems.org"
gem 'json', '>= 1.5.1'
-gem 'algolia', '>= 3.4.0'
+gem 'algolia', '>= 3.5.0'
if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
gem 'rubysl', '~> 2.0', :platform => :rbx
From bc48f9aac7ca463f25ef2076c7a02b49a1d136c7 Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 10:07:36 +0200
Subject: [PATCH 09/40] fix: virtual replica test
---
spec/integration_spec.rb | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/spec/integration_spec.rb b/spec/integration_spec.rb
index bd998bd..b741aab 100644
--- a/spec/integration_spec.rb
+++ b/spec/integration_spec.rb
@@ -1387,10 +1387,10 @@ class ForwardToReplicasTwo < ActiveRecord::Base
if v[0][:replica]
expect(v[0][:index_name]).to eq(safe_index_name("VirtualReplica_replica"))
expect(v[0][:virtual]).to eq(true)
- expect(v[1].to_settings[:replicas]).to be_nil
+ expect(v[1].to_settings.replicas).to be_nil
else
expect(v[0][:index_name]).to eq(safe_index_name("VirtualReplica_primary"))
- expect(v[1].to_settings[:replicas]).to match_array(["virtual(#{safe_index_name("VirtualReplica_replica")})"])
+ expect(v[1].to_settings.replicas).to match_array(["virtual(#{safe_index_name("VirtualReplica_replica")})"])
end
end
end
From 799818283d22681f6697d63e2b4f5f4c23bd1aae Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 10:21:33 +0200
Subject: [PATCH 10/40] test matrix
---
.circleci/config.yml | 51 +++++++++-----------------------------------
1 file changed, 10 insertions(+), 41 deletions(-)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 171c83e..7c007b6 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -69,45 +69,14 @@ workflows:
ci:
jobs:
- test:
- name: 'Rails 5.1 - Ruby 2.4'
- version: '2.4'
- rails-version: '5.1'
- sequel-version: '5.0'
+ matrix:
+ parameters:
+ version: [ '2.5', '2.6', '2.7', '3.0', '3.1' ]
+ rails-version: [ '6.0', '6.1' ]
+ sequel-version: [ '5.0' ]
- test:
- name: 'Rails 5.1 - Ruby 2.5'
- version: '2.5'
- rails-version: '5.1'
- sequel-version: '5.0'
- - test:
- name: 'Rails 5.1 - Ruby 2.6'
- version: '2.6'
- rails-version: '5.1'
- sequel-version: '5.0'
-
-
- - test:
- name: 'Rails 6.0 - Ruby 2.5'
- version: '2.5'
- rails-version: '6.0'
- sequel-version: '5.0'
- - test:
- name: 'Rails 6.0 - Ruby 2.6'
- version: '2.6'
- rails-version: '6.0'
- sequel-version: '5.0'
- - test:
- name: 'Rails 6.0 - Ruby 2.7'
- version: '2.7'
- rails-version: '6.0'
- sequel-version: '5.0'
-
- - test:
- name: 'Rails 6.1 - Ruby 2.7'
- version: '2.7'
- rails-version: '6.1'
- sequel-version: '5.0'
- - test:
- name: 'Rails 6.1 - Ruby 3.0'
- version: '3.0'
- rails-version: '6.1'
- sequel-version: '5.0'
+ matrix:
+ parameters:
+ version: ['3.0', '3.1']
+ rails-version: ['7.0']
+ sequel-version: ['5.0']
\ No newline at end of file
From c41e65d93343b472418cfd32046f9a44e5677a24 Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 10:23:27 +0200
Subject: [PATCH 11/40] Update Gemfile
---
Gemfile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Gemfile b/Gemfile
index 4143eab..29688ef 100644
--- a/Gemfile
+++ b/Gemfile
@@ -27,7 +27,7 @@ group :test do
end
group :development do
- gem 'rake', '~> 10.1.0'
+ gem 'rake', '>= 10.1.0'
gem 'rdoc'
end
From bfe1a898959ba196f2810df6bf90df1ce3d34fcf Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 10:25:24 +0200
Subject: [PATCH 12/40] Update config.yml
---
.circleci/config.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 7c007b6..6812d11 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -33,7 +33,7 @@ aliases:
references:
default_docker_ruby_executor: &default_docker_ruby_executor
- image: circleci/ruby:<< parameters.version >>
+ image: cimg/ruby:<< parameters.version >>
environment:
BUNDLE_JOBS: 3
BUNDLE_RETRY: 3
From 99e68dbf02c7f5e9fe5f4dfcf83545ef05a2e5fe Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 10:28:07 +0200
Subject: [PATCH 13/40] Update Gemfile
---
Gemfile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Gemfile b/Gemfile
index 29688ef..83d5347 100644
--- a/Gemfile
+++ b/Gemfile
@@ -16,7 +16,7 @@ group :test do
else
gem 'sqlite3', '< 1.4.0', :platform => [:rbx, :ruby]
end
- gem 'rspec', '>= 2.5.0', '< 3.0'
+ gem 'rspec', '~> 3.0'
gem 'jdbc-sqlite3', :platform => :jruby
gem 'activerecord-jdbc-adapter', :platform => :jruby
gem 'activerecord-jdbcsqlite3-adapter', :platform => :jruby
From 544278fa4c8df8c794d3db065f86dadb73fdcd78 Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 10:30:10 +0200
Subject: [PATCH 14/40] Update config.yml
---
.circleci/config.yml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 6812d11..b11231e 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -6,6 +6,10 @@ aliases:
curl -s https://algoliasearch-client-keygen.herokuapp.com | sh >> $BASH_ENV
fi
+ - &install_sqlite
+ name: Install SQLite
+ command: apt-get install libsqlite3-dev
+
- &check_bundler
name: Which bundler?
command: bundle -v
@@ -57,6 +61,7 @@ jobs:
- *default_docker_ruby_executor
steps:
- checkout
+ - run: *install_sqlite
- run: *check_bundler
- restore_cache: *restore_cache
- run: *install_bundler
From f5f0e3da17ffc6fd44d5cf7a0e0f06e6640b5833 Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 10:32:34 +0200
Subject: [PATCH 15/40] Update config.yml
---
.circleci/config.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index b11231e..c6e59d5 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -8,7 +8,7 @@ aliases:
- &install_sqlite
name: Install SQLite
- command: apt-get install libsqlite3-dev
+ command: sudo apt-get update && sudo apt-get install -y sqlite3 libsqlite3-dev
- &check_bundler
name: Which bundler?
From a7f295290efb6e30d51cd626d60bc8860896991c Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 10:42:51 +0200
Subject: [PATCH 16/40] Update algoliasearch-rails.rb
---
lib/algoliasearch-rails.rb | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/lib/algoliasearch-rails.rb b/lib/algoliasearch-rails.rb
index 9abd18b..b75000e 100644
--- a/lib/algoliasearch-rails.rb
+++ b/lib/algoliasearch-rails.rb
@@ -179,10 +179,9 @@ def get_attributes(object)
if @options[:sanitize]
sanitizer = begin
- ::HTML::FullSanitizer.new
+ ::Rails::Html5::FullSanitizer.new
rescue NameError
- # from rails 4.2
- ::Rails::Html::FullSanitizer.new
+ ::HTML::FullSanitizer.new
end
attributes = sanitize_attributes(attributes, sanitizer)
end
From 2e25bb1a0d7530bd6a4e2c388116c93fa840ac91 Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 10:52:47 +0200
Subject: [PATCH 17/40] sanitizer
---
lib/algoliasearch-rails.rb | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lib/algoliasearch-rails.rb b/lib/algoliasearch-rails.rb
index b75000e..447c42e 100644
--- a/lib/algoliasearch-rails.rb
+++ b/lib/algoliasearch-rails.rb
@@ -179,7 +179,9 @@ def get_attributes(object)
if @options[:sanitize]
sanitizer = begin
- ::Rails::Html5::FullSanitizer.new
+ ::Rails::Html::Sanitizer.new
+ rescue NameError
+ ::Rails::HTML::FullSanitizer.new
rescue NameError
::HTML::FullSanitizer.new
end
From d158342f235ed38a6e5bf35d124476588260f60b Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 11:00:58 +0200
Subject: [PATCH 18/40] Update algoliasearch-rails.rb
---
lib/algoliasearch-rails.rb | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/lib/algoliasearch-rails.rb b/lib/algoliasearch-rails.rb
index 447c42e..3715a61 100644
--- a/lib/algoliasearch-rails.rb
+++ b/lib/algoliasearch-rails.rb
@@ -179,11 +179,9 @@ def get_attributes(object)
if @options[:sanitize]
sanitizer = begin
- ::Rails::Html::Sanitizer.new
+ ::Rails::HTML5::FullSanitizer.new
rescue NameError
::Rails::HTML::FullSanitizer.new
- rescue NameError
- ::HTML::FullSanitizer.new
end
attributes = sanitize_attributes(attributes, sanitizer)
end
From 9e698f4dedad4dc2f4f5af765d7877ec72bdd3ea Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 11:08:24 +0200
Subject: [PATCH 19/40] Update algoliasearch-rails.rb
---
lib/algoliasearch-rails.rb | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/algoliasearch-rails.rb b/lib/algoliasearch-rails.rb
index 3715a61..24a6d62 100644
--- a/lib/algoliasearch-rails.rb
+++ b/lib/algoliasearch-rails.rb
@@ -179,9 +179,9 @@ def get_attributes(object)
if @options[:sanitize]
sanitizer = begin
- ::Rails::HTML5::FullSanitizer.new
+ ::Rails::Html::FullSanitizer.new
rescue NameError
- ::Rails::HTML::FullSanitizer.new
+ ::HTML::FullSanitizer.new
end
attributes = sanitize_attributes(attributes, sanitizer)
end
From 74413b0ed55442c63a6a638d00e602301119c9b2 Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 11:23:38 +0200
Subject: [PATCH 20/40] Update algoliasearch-rails.rb
---
lib/algoliasearch-rails.rb | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/lib/algoliasearch-rails.rb b/lib/algoliasearch-rails.rb
index 24a6d62..63cca17 100644
--- a/lib/algoliasearch-rails.rb
+++ b/lib/algoliasearch-rails.rb
@@ -178,11 +178,12 @@ def get_attributes(object)
attributes.merge!(attributes_to_hash(@additional_attributes, object)) if @additional_attributes
if @options[:sanitize]
- sanitizer = begin
- ::Rails::Html::FullSanitizer.new
- rescue NameError
- ::HTML::FullSanitizer.new
+ sanitizer = if Rails::VERSION::MAJOR >= 7
+ Rails::Html::Sanitizer.new
+ else
+ Rails::Html::FullSanitizer.new
end
+
attributes = sanitize_attributes(attributes, sanitizer)
end
From 5b6af12bdc9b20e7ca26707815bb1270f065483c Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 11:42:56 +0200
Subject: [PATCH 21/40] Update pagy.rb
---
lib/algoliasearch/pagination/pagy.rb | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/lib/algoliasearch/pagination/pagy.rb b/lib/algoliasearch/pagination/pagy.rb
index b684731..350775c 100644
--- a/lib/algoliasearch/pagination/pagy.rb
+++ b/lib/algoliasearch/pagination/pagy.rb
@@ -5,6 +5,8 @@
module AlgoliaSearch
module Pagination
class Pagy
+ include Pagy::Backend if defined? Pagy::Backend
+
def self.create(results, total_hits, options = {})
vars = {
count: total_hits,
@@ -12,8 +14,7 @@ def self.create(results, total_hits, options = {})
items: options[:per_page]
}
- pagy = ::Pagy.new(vars)
- [pagy, results]
+ pagy(results, vars)
end
end
From f421f5243989eb93cfdba167e958b44d6b07cbdb Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 11:44:58 +0200
Subject: [PATCH 22/40] Update integration_spec.rb
---
spec/integration_spec.rb | 21 ++++-----------------
1 file changed, 4 insertions(+), 17 deletions(-)
diff --git a/spec/integration_spec.rb b/spec/integration_spec.rb
index b741aab..dda460a 100644
--- a/spec/integration_spec.rb
+++ b/spec/integration_spec.rb
@@ -1434,24 +1434,11 @@ class ForwardToReplicasTwo < ActiveRecord::Base
it "should sanitize attributes" do
@hack = Book.create! :name => "\"> hack0r", :author => "", :premium => true, :released => true
b = Book.raw_search('hack')
+
expect(b[:hits].length).to eq(1)
- begin
- expect(b[:hits][0][:name]).to eq('"> hack0r')
- expect(b[:hits][0][:author]).to eq('alert(1)')
- expect(b[:hits][0][:_highlightResult][:name][:value]).to eq('"> hack0r')
- rescue
- # rails 4.2's sanitizer
- begin
- expect(b[:hits][0][:name]).to eq('"> hack0r')
- expect(b[:hits][0][:author]).to eq('')
- expect(b[:hits][0][:_highlightResult][:name][:value]).to eq('"> hack0r')
- rescue
- # jruby
- expect(b[:hits][0][:name]).to eq('"> hack0r')
- expect(b[:hits][0][:author]).to eq('')
- expect(b[:hits][0][:_highlightResult][:name][:value]).to eq('"> hack0r')
- end
- end
+ expect(b[:hits][0][:name]).to eq('"> hack0r')
+ expect(b[:hits][0][:author]).to eq('alert(1)')
+ expect(b[:hits][0][:_highlightResult][:name][:value]).to eq('"> hack0r')
end
it "should handle removal in an extra index" do
From dbbcc769c128e155af33dbe742ef6e2d3f3f6057 Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 11:54:20 +0200
Subject: [PATCH 23/40] Update pagy.rb
---
lib/algoliasearch/pagination/pagy.rb | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/algoliasearch/pagination/pagy.rb b/lib/algoliasearch/pagination/pagy.rb
index 350775c..bf56761 100644
--- a/lib/algoliasearch/pagination/pagy.rb
+++ b/lib/algoliasearch/pagination/pagy.rb
@@ -5,7 +5,6 @@
module AlgoliaSearch
module Pagination
class Pagy
- include Pagy::Backend if defined? Pagy::Backend
def self.create(results, total_hits, options = {})
vars = {
@@ -14,7 +13,8 @@ def self.create(results, total_hits, options = {})
items: options[:per_page]
}
- pagy(results, vars)
+ pagy = ::Pagy.new(vars)
+ [pagy, results]
end
end
From 1ecad6c62b34f1899b6bdcfe19db878252a4c1ee Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 12:01:01 +0200
Subject: [PATCH 24/40] Update integration_spec.rb
---
spec/integration_spec.rb | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/spec/integration_spec.rb b/spec/integration_spec.rb
index dda460a..4d894f1 100644
--- a/spec/integration_spec.rb
+++ b/spec/integration_spec.rb
@@ -1437,8 +1437,8 @@ class ForwardToReplicasTwo < ActiveRecord::Base
expect(b[:hits].length).to eq(1)
expect(b[:hits][0][:name]).to eq('"> hack0r')
- expect(b[:hits][0][:author]).to eq('alert(1)')
- expect(b[:hits][0][:_highlightResult][:name][:value]).to eq('"> hack0r')
+ expect(b[:hits][0][:author]).to eq('')
+ expect(b[:hits][0][:_highlightResult][:name][:value]).to eq('"> hack0r')
end
it "should handle removal in an extra index" do
From 1bba7f374ca8986fccc0612c4cdda374d308beb7 Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 12:01:57 +0200
Subject: [PATCH 25/40] Update pagy.rb
---
lib/algoliasearch/pagination/pagy.rb | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/lib/algoliasearch/pagination/pagy.rb b/lib/algoliasearch/pagination/pagy.rb
index bf56761..54c9ecd 100644
--- a/lib/algoliasearch/pagination/pagy.rb
+++ b/lib/algoliasearch/pagination/pagy.rb
@@ -13,7 +13,13 @@ def self.create(results, total_hits, options = {})
items: options[:per_page]
}
- pagy = ::Pagy.new(vars)
+ pagy_version = Gem::Version.new(::Pagy::VERSION)
+ pagy = if pagy_version >= 9
+ ::Pagy.new(**vars)
+ else
+ ::Pagy.new(vars)
+ end
+
[pagy, results]
end
end
From 8a32e9b5ebfcea5a40ab9a5bd6c5f8970f20fe8a Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 12:17:03 +0200
Subject: [PATCH 26/40] Update pagy.rb
---
lib/algoliasearch/pagination/pagy.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/algoliasearch/pagination/pagy.rb b/lib/algoliasearch/pagination/pagy.rb
index 54c9ecd..520de28 100644
--- a/lib/algoliasearch/pagination/pagy.rb
+++ b/lib/algoliasearch/pagination/pagy.rb
@@ -14,7 +14,7 @@ def self.create(results, total_hits, options = {})
}
pagy_version = Gem::Version.new(::Pagy::VERSION)
- pagy = if pagy_version >= 9
+ pagy = if pagy_version >= Gem::Version.new('9.0')
::Pagy.new(**vars)
else
::Pagy.new(vars)
From 28364461c9f7e1e54d46574b4f51c56cc7112183 Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 12:40:13 +0200
Subject: [PATCH 27/40] Update integration_spec.rb
---
spec/integration_spec.rb | 1 -
1 file changed, 1 deletion(-)
diff --git a/spec/integration_spec.rb b/spec/integration_spec.rb
index 4d894f1..d01ef0e 100644
--- a/spec/integration_spec.rb
+++ b/spec/integration_spec.rb
@@ -1533,7 +1533,6 @@ class ForwardToReplicasTwo < ActiveRecord::Base
it "should paginate" do
pagy, cities = City.search '', :hitsPerPage => 2
pagy.page.should eq(1)
- pagy.items.should eq(2)
pagy.count.should eq(City.raw_search('')[:nbHits])
cities.length.should eq(2)
cities.should be_an(Array)
From 91ccfc56c4aecfc98a41574e6c3a8e6bd0fc6b76 Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 12:42:14 +0200
Subject: [PATCH 28/40] Update integration_spec.rb
---
spec/integration_spec.rb | 2 ++
1 file changed, 2 insertions(+)
diff --git a/spec/integration_spec.rb b/spec/integration_spec.rb
index d01ef0e..041d7e2 100644
--- a/spec/integration_spec.rb
+++ b/spec/integration_spec.rb
@@ -1406,6 +1406,8 @@ class ForwardToReplicasTwo < ActiveRecord::Base
end
describe 'Book' do
+ require 'rails-html-sanitizer'
+
before(:all) do
Book.clear_index!(true)
index_name_author = Book.index_name(nil, safe_index_name('BookAuthor'))
From 079c71da7c51fccf69451380e88f9633f9bc8834 Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 13:46:54 +0200
Subject: [PATCH 29/40] sanitizer
---
lib/algoliasearch-rails.rb | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/lib/algoliasearch-rails.rb b/lib/algoliasearch-rails.rb
index 63cca17..79668a8 100644
--- a/lib/algoliasearch-rails.rb
+++ b/lib/algoliasearch-rails.rb
@@ -176,16 +176,7 @@ def get_attributes(object)
end
attributes.merge!(attributes_to_hash(@additional_attributes, object)) if @additional_attributes
-
- if @options[:sanitize]
- sanitizer = if Rails::VERSION::MAJOR >= 7
- Rails::Html::Sanitizer.new
- else
- Rails::Html::FullSanitizer.new
- end
-
- attributes = sanitize_attributes(attributes, sanitizer)
- end
+ attributes = sanitize_attributes(attributes, Rails::Html::FullSanitizer.new) if @options[:sanitize]
if @options[:force_utf8_encoding] && Object.const_defined?(:RUBY_VERSION) && RUBY_VERSION.to_f > 1.8
attributes = encode_attributes(attributes)
From cd3c1de8b392b18240e29b7e9bfb52ea50a10bfa Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 15:42:54 +0200
Subject: [PATCH 30/40] chore: clean up algoliasearch/configuration
---
lib/algoliasearch/configuration.rb | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/lib/algoliasearch/configuration.rb b/lib/algoliasearch/configuration.rb
index 3b6bda3..13aeaad 100644
--- a/lib/algoliasearch/configuration.rb
+++ b/lib/algoliasearch/configuration.rb
@@ -2,7 +2,6 @@ module AlgoliaSearch
module Configuration
REQUIRED_CONFIGURATION = {
user_agent: "Algolia for Rails (#{AlgoliaSearch::VERSION}); Rails (#{defined?(::Rails::VERSION::STRING) ? ::Rails::VERSION::STRING : 'unknown'})",
- symbolize_keys: false
}
def initialize
@@ -21,14 +20,6 @@ def configuration=(configuration)
.merge({ user_agent: user_agent })
end
- def client_opts
- @@opts ||= {}
- end
-
- def client_opts=(opts)
- @@opts = opts
- end
-
def client
if @client.nil?
setup_client
@@ -37,7 +28,6 @@ def client
@client
end
- # TODO
def setup_client
@client = Algolia::SearchClient.create(@@configuration[:application_id], @@configuration[:api_key])
end
From 531d98a4f6d471926104ff57509dfbf9f04b0d34 Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 15:48:04 +0200
Subject: [PATCH 31/40] remove `index` method
---
lib/algoliasearch-rails.rb | 12 ------------
1 file changed, 12 deletions(-)
diff --git a/lib/algoliasearch-rails.rb b/lib/algoliasearch-rails.rb
index 79668a8..87edc4b 100644
--- a/lib/algoliasearch-rails.rb
+++ b/lib/algoliasearch-rails.rb
@@ -378,7 +378,6 @@ class <
Date: Mon, 14 Oct 2024 16:02:28 +0200
Subject: [PATCH 32/40] chore: handle todos
---
lib/algoliasearch-rails.rb | 150 ++++++-------------------------------
spec/integration_spec.rb | 28 +++----
2 files changed, 38 insertions(+), 140 deletions(-)
diff --git a/lib/algoliasearch-rails.rb b/lib/algoliasearch-rails.rb
index 87edc4b..a702677 100644
--- a/lib/algoliasearch-rails.rb
+++ b/lib/algoliasearch-rails.rb
@@ -230,7 +230,6 @@ def get_setting(name)
instance_variable_get("@#{name}")
end
- # TODO
def to_settings
settings = to_hash
@@ -297,71 +296,6 @@ def additional_indexes
autoload :AlgoliaJob, 'algoliasearch/algolia_job'
end
- # this class wraps an Algolia::Index object ensuring all raised exceptions
- # are correctly logged or thrown depending on the `raise_on_failure` option
- # TODO
- class SafeIndex
- def initialize(name, raise_on_failure)
- @index = AlgoliaSearch.client.init_index(name)
- @raise_on_failure = raise_on_failure.nil? || raise_on_failure
- end
-
- # ::Algolia::Search::Index.instance_methods(false).each do |m|
- # define_method(m) do |*args, &block|
- # SafeIndex.log_or_throw(m, @raise_on_failure) do
- # @index.send(m, *args, &block)
- # end
- # end
- # end
-
- # special handling of wait_task to handle null task_id
- def wait_task(task_id)
- return if task_id.nil? && !@raise_on_failure # ok
- SafeIndex.log_or_throw(:wait_task, @raise_on_failure) do
- @index.wait_task(task_id)
- end
- end
-
- # special handling of get_settings to avoid raising errors on 404
- def get_settings(*args)
- SafeIndex.log_or_throw(:get_settings, @raise_on_failure) do
- begin
- @index.get_settings(*args)
- rescue Algolia::AlgoliaHttpError => e
- return {} if e.code == 404 # not fatal
- raise e
- end
- end
- end
-
- # expose move as well
- def self.move_index(old_name, new_name)
- SafeIndex.log_or_throw(:move_index, true) do
- AlgoliaSearch.client.move_index(old_name, new_name)
- end
- end
-
- private
- def self.log_or_throw(method, raise_on_failure, &block)
- begin
- yield
- rescue Algolia::AlgoliaError => e
- raise e if raise_on_failure
- # log the error
- (Rails.logger || Logger.new(STDOUT)).error("[algoliasearch-rails] #{e.message}")
- # return something
- case method.to_s
- when 'search'
- # some attributes are required
- { 'hits' => [], 'hitsPerPage' => 0, 'page' => 0, 'facets' => {}, 'error' => e }
- else
- # empty answer
- { 'error' => e }
- end
- end
- end
- end
-
# these are the class methods added when AlgoliaSearch is included
module ClassMethods
@@ -503,12 +437,11 @@ def algolia_without_auto_index_scope
Thread.current["algolia_without_auto_index_scope_for_#{self.model_name}"]
end
- # TODO
def algolia_reindex!(batch_size = AlgoliaSearch::IndexSettings::DEFAULT_BATCH_SIZE, synchronous = false)
return if algolia_without_auto_index_scope
algolia_configurations.each do |options, settings|
next if algolia_indexing_disabled?(options)
- ensure_init_new(options, settings)
+ algolia_ensure_init(options, settings)
index_name = algolia_index_name(options)
next if options[:replica]
last_task = nil
@@ -535,7 +468,6 @@ def algolia_reindex!(batch_size = AlgoliaSearch::IndexSettings::DEFAULT_BATCH_SI
nil
end
- # TODO
# reindex whole database using a extra temporary index + move operation
def algolia_reindex(batch_size = AlgoliaSearch::IndexSettings::DEFAULT_BATCH_SIZE, synchronous = false)
return if algolia_without_auto_index_scope
@@ -543,11 +475,10 @@ def algolia_reindex(batch_size = AlgoliaSearch::IndexSettings::DEFAULT_BATCH_SIZ
next if algolia_indexing_disabled?(options)
next if options[:replica]
- ensure_init_new(options, settings)
+ algolia_ensure_init(options, settings)
index_name = algolia_index_name(options)
# fetch the master settings
-
master_settings = AlgoliaSearch.client.get_settings(index_name).to_hash rescue {} # if master doesn't exist yet
master_exists = master_settings != {}
master_settings.merge!(settings.to_hash)
@@ -589,29 +520,36 @@ def algolia_reindex(batch_size = AlgoliaSearch::IndexSettings::DEFAULT_BATCH_SIZ
nil
end
- # TODO
def algolia_set_settings(synchronous = false)
algolia_configurations.each do |options, settings|
if options[:primary_settings] && options[:inherit]
- primary = options[:primary_settings].to_settings
+ primary = options[:primary_settings].to_settings.to_hash
primary.delete :replicas
primary.delete 'replicas'
- final_settings = primary.merge(settings.to_settings)
+ final_settings = primary.merge(settings.to_settings.to_hash)
else
- final_settings = settings.to_settings
+ final_settings = settings.to_settings.to_hash
end
- index = SafeIndex.new(algolia_index_name(options), true)
- task = index.set_settings(final_settings)
- index.wait_task(task.raw_response["taskID"]) if synchronous
+ s = final_settings.map do |k, v|
+ [settings.setting_name(k), v]
+ end.to_h
+
+ synonyms = s.delete("synonyms") || s.delete(:synonyms)
+ unless synonyms.nil? || synonyms.empty?
+ resp = AlgoliaSearch.client.save_synonyms(index_name,synonyms.map {|s| Algolia::Search::SynonymHit.new({object_id: s.join("-"), synonyms: s, type: "synonym"}) } )
+ AlgoliaSearch.client.wait_for_task(index_name, resp.task_id) if synchronous
+ end
+
+ resp = AlgoliaSearch.client.set_settings(index_name, Algolia::Search::IndexSettings.new(s))
+ AlgoliaSearch.client.wait_for_task(index_name, resp.task_id) if synchronous
end
end
- # TODO
def algolia_index_objects(objects, synchronous = false)
algolia_configurations.each do |options, settings|
next if algolia_indexing_disabled?(options)
- ensure_init_new(options, settings)
+ algolia_ensure_init(options, settings)
index_name = algolia_index_name(options)
next if options[:replica]
@@ -622,7 +560,6 @@ def algolia_index_objects(objects, synchronous = false)
end
end
- # TODO
def algolia_index!(object, synchronous = false)
return if algolia_without_auto_index_scope
algolia_configurations.each do |options, settings|
@@ -630,7 +567,7 @@ def algolia_index!(object, synchronous = false)
object_id = algolia_object_id_of(object, options)
index_name = algolia_index_name(options)
- ensure_init_new(options, settings)
+ algolia_ensure_init(options, settings)
next if options[:replica]
if algolia_indexable?(object, options)
@@ -650,14 +587,13 @@ def algolia_index!(object, synchronous = false)
nil
end
- # TODO
def algolia_remove_from_index!(object, synchronous = false)
return if algolia_without_auto_index_scope
object_id = algolia_object_id_of(object)
raise ArgumentError.new("Cannot index a record with a blank objectID") if object_id.blank?
algolia_configurations.each do |options, settings|
next if algolia_indexing_disabled?(options)
- ensure_init_new(options, settings)
+ algolia_ensure_init(options, settings)
index_name = algolia_index_name(options)
next if options[:replica]
@@ -670,12 +606,11 @@ def algolia_remove_from_index!(object, synchronous = false)
nil
end
- # TODO
def algolia_clear_index!(synchronous = false)
algolia_configurations.each do |options, settings|
next if algolia_indexing_disabled?(options) || options[:replica]
- ensure_init_new(options, settings)
+ algolia_ensure_init(options, settings)
index_name = algolia_index_name(options)
res = AlgoliaSearch.client.clear_objects(index_name)
@@ -686,7 +621,6 @@ def algolia_clear_index!(synchronous = false)
nil
end
- # TODO
def algolia_raw_search(q, params = {})
index_name_base = params.delete(:index) ||
@@ -730,7 +664,6 @@ def algolia_init_raw_answer(json)
end
end
- # TODO
def algolia_search(q, params = {})
if AlgoliaSearch.configuration[:pagination_backend]
# kaminari, will_paginate, and pagy start pagination at 1, Algolia starts at 0
@@ -764,7 +697,6 @@ def algolia_search(q, params = {})
res
end
- # TODO
def algolia_search_for_facet_values(facet, text, params = {})
index_name = params.delete(:index) ||
params.delete('index') ||
@@ -782,11 +714,11 @@ def algolia_search_for_facet_values(facet, text, params = {})
def ensure_algolia_index(name = nil)
if name
algolia_configurations.each do |o, s|
- return ensure_init_new(o, s) if o[:index_name].to_s == name.to_s
+ return algolia_ensure_init(o, s) if o[:index_name].to_s == name.to_s
end
raise ArgumentError.new("Invalid index/replica name: #{name}")
end
- ensure_init_new
+ algolia_ensure_init
end
def algolia_index_name(options = nil, index_name = nil)
@@ -826,40 +758,7 @@ def algolia_must_reindex?(object)
protected
- # TODO - deprecate
- def algolia_ensure_init(options = nil, settings = nil, index_settings = nil)
- raise ArgumentError.new('No `algoliasearch` block found in your model.') if algoliasearch_settings.nil?
-
- @algolia_indexes ||= {}
-
- options ||= algoliasearch_options
- settings ||= algoliasearch_settings
-
- return @algolia_indexes[settings] if @algolia_indexes[settings]
-
- @algolia_indexes[settings] = SafeIndex.new(algolia_index_name(options), algoliasearch_options[:raise_on_failure])
-
- index_settings ||= settings.to_settings
- index_settings = options[:primary_settings].to_settings.merge(index_settings) if options[:inherit]
- replicas = index_settings.delete(:replicas) ||
- index_settings.delete('replicas')
- index_settings[:replicas] = replicas unless replicas.nil? || options[:inherit]
-
- options[:check_settings] = true if options[:check_settings].nil?
-
- current_settings = if options[:check_settings] && !algolia_indexing_disabled?(options)
- @algolia_indexes[settings].get_settings(:getVersion => 1) rescue nil # if the index doesn't exist
- end
-
- if !algolia_indexing_disabled?(options) && options[:check_settings] && algoliasearch_settings_changed?(current_settings, index_settings)
- set_settings_method = options[:synchronous] ? :set_settings! : :set_settings
- @algolia_indexes[settings].send(set_settings_method, index_settings)
- end
-
- @algolia_indexes[settings]
- end
-
- def ensure_init_new(options = nil, settings = nil, index_settings_hash = nil)
+ def algolia_ensure_init(options = nil, settings = nil, index_settings_hash = nil)
raise ArgumentError.new('No `algoliasearch` block found in your model.') if algoliasearch_settings.nil?
@algolia_indexes_init ||= {}
@@ -903,7 +802,6 @@ def ensure_init_new(options = nil, settings = nil, index_settings_hash = nil)
private
- # TODO
def algolia_configurations
raise ArgumentError.new('No `algoliasearch` block found in your model.') if algoliasearch_settings.nil?
if @configurations.nil?
diff --git a/spec/integration_spec.rb b/spec/integration_spec.rb
index 041d7e2..88b952e 100644
--- a/spec/integration_spec.rb
+++ b/spec/integration_spec.rb
@@ -366,7 +366,7 @@ def public?
describe 'DisabledIndexing' do
it 'should not call get_settings' do
expect_any_instance_of(Algolia::SearchClient).not_to receive(:get_settings)
- DisabledIndexing.send(:ensure_init_new)
+ DisabledIndexing.send(:algolia_ensure_init)
end
end
@@ -392,7 +392,7 @@ class EnableCheckSettingsSynchronously < ActiveRecord::Base
it 'should call set_setting with wait_task(sync)' do
expect_any_instance_of(Algolia::SearchClient).to receive(:set_settings).and_call_original # wait_task use this return val
expect_any_instance_of(Algolia::SearchClient).to receive(:wait_for_task)
- EnableCheckSettingsSynchronously.send(:ensure_init_new)
+ EnableCheckSettingsSynchronously.send(:algolia_ensure_init)
end
end
@@ -403,7 +403,7 @@ class EnableCheckSettingsSynchronously < ActiveRecord::Base
it 'should not call set_setting' do
expect_any_instance_of(Algolia::SearchClient).not_to receive(:set_settings)
- EnableCheckSettingsSynchronously.send(:ensure_init_new)
+ EnableCheckSettingsSynchronously.send(:algolia_ensure_init)
end
end
end
@@ -430,7 +430,7 @@ class EnableCheckSettingsAsynchronously < ActiveRecord::Base
it 'should call set_setting without wait_task(sync)' do
expect_any_instance_of(Algolia::SearchClient).to receive(:set_settings)
expect_any_instance_of(Algolia::SearchClient).not_to receive(:wait_for_task)
- EnableCheckSettingsAsynchronously.send(:ensure_init_new)
+ EnableCheckSettingsAsynchronously.send(:algolia_ensure_init)
end
end
@@ -441,7 +441,7 @@ class EnableCheckSettingsAsynchronously < ActiveRecord::Base
it 'should not call set_setting' do
expect_any_instance_of(Algolia::SearchClient).not_to receive(:set_settings)
- EnableCheckSettingsAsynchronously.send(:ensure_init_new)
+ EnableCheckSettingsAsynchronously.send(:algolia_ensure_init)
end
end
end
@@ -453,7 +453,7 @@ class EnableCheckSettingsAsynchronously < ActiveRecord::Base
it 'should call get_settings' do
expect_any_instance_of(Algolia::SearchClient).to receive(:get_settings)
- SequelBook.send(:ensure_init_new)
+ SequelBook.send(:algolia_ensure_init)
end
it "should index the book" do
@@ -1254,7 +1254,7 @@ class ForwardToReplicas < ActiveRecord::Base
end
it 'shouldn\'t have inherited from the primary' do
- ForwardToReplicas.send :ensure_init_new
+ ForwardToReplicas.send :algolia_ensure_init
# Hacky way to have a wait on set_settings
ForwardToReplicas.create(:name => 'val')
@@ -1292,9 +1292,9 @@ class ForwardToReplicasTwo < ActiveRecord::Base
end
end
- ForwardToReplicas.send :ensure_init_new
+ ForwardToReplicas.send :algolia_ensure_init
- ForwardToReplicasTwo.send :ensure_init_new
+ ForwardToReplicasTwo.send :algolia_ensure_init
# Hacky way to have a wait on set_settings
ForwardToReplicasTwo.create(:name => 'val')
@@ -1332,7 +1332,7 @@ class ForwardToReplicasTwo < ActiveRecord::Base
end
end
- ForwardToReplicas.send :ensure_init_new
+ ForwardToReplicas.send :algolia_ensure_init
# Hacky way to hook replica settings update
ForwardToReplicas.create(:name => 'val')
@@ -1340,7 +1340,7 @@ class ForwardToReplicasTwo < ActiveRecord::Base
expect_any_instance_of(Algolia::SearchClient).not_to receive(:set_settings)
- ForwardToReplicasTwo.send :ensure_init_new
+ ForwardToReplicasTwo.send :algolia_ensure_init
# Hacky way to hook replica settings update
ForwardToReplicasTwo.create(:name => 'val2')
@@ -1543,9 +1543,9 @@ class ForwardToReplicasTwo < ActiveRecord::Base
describe 'Disabled' do
before(:all) do
- DisabledBoolean.send(:ensure_init_new)
- DisabledProc.send(:ensure_init_new)
- DisabledSymbol.send(:ensure_init_new)
+ DisabledBoolean.send(:algolia_ensure_init)
+ DisabledProc.send(:algolia_ensure_init)
+ DisabledSymbol.send(:algolia_ensure_init)
end
it "should disable the indexing using a boolean" do
From 8338b5295cfd4f12a1ae73707b287605172e4715 Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 16:06:50 +0200
Subject: [PATCH 33/40] Update algoliasearch-rails.gemspec
---
algoliasearch-rails.gemspec | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/algoliasearch-rails.gemspec b/algoliasearch-rails.gemspec
index af05a53..1273172 100644
--- a/algoliasearch-rails.gemspec
+++ b/algoliasearch-rails.gemspec
@@ -79,7 +79,7 @@ Gem::Specification.new do |s|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
s.add_runtime_dependency(%q, [">= 1.5.1"])
- s.add_runtime_dependency(%q, ["< 3.0.0"])
+ s.add_runtime_dependency(%q, [">= 3.5.0"])
s.add_development_dependency(%q, [">= 2.3.15"])
s.add_development_dependency(%q, [">= 0"])
s.add_development_dependency(%q, [">= 0"])
@@ -87,7 +87,7 @@ Gem::Specification.new do |s|
s.add_development_dependency "rdoc"
else
s.add_dependency(%q, [">= 1.5.1"])
- s.add_dependency(%q, ["< 3.0.0"])
+ s.add_dependency(%q, [">= 3.5.0"])
end
else
s.add_dependency(%q, [">= 1.5.1"])
From 7c56ebe394a914e511093999c3e46914a19472ff Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 16:16:14 +0200
Subject: [PATCH 34/40] Update spec_helper.rb
---
spec/spec_helper.rb | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 8860569..4f4175f 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -32,8 +32,12 @@
# Remove all indexes setup in this run in local or CI
c.after(:suite) do
safe_index_list.each do |i|
- res = AlgoliaSearch.client.delete_index(i.name)
- AlgoliaSearch.client.wait_for_task(i.name, res.task_id)
+ begin
+ res = AlgoliaSearch.client.delete_index(i.name)
+ AlgoliaSearch.client.wait_for_task(i.name, res.task_id)
+ rescue
+ # fail gracefully
+ end
end
end
end
From fc5e4a1cfcbbb0e09c8661a4fc7b83e720fa1f43 Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Mon, 14 Oct 2024 17:56:07 +0200
Subject: [PATCH 35/40] address feedback
---
lib/algoliasearch-rails.rb | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/algoliasearch-rails.rb b/lib/algoliasearch-rails.rb
index a702677..21ee87f 100644
--- a/lib/algoliasearch-rails.rb
+++ b/lib/algoliasearch-rails.rb
@@ -496,7 +496,7 @@ def algolia_reindex(batch_size = AlgoliaSearch::IndexSettings::DEFAULT_BATCH_SIZ
if options[:check_settings] == false && master_exists
task_id = AlgoliaSearch.client.operation_index(
index_name,
- Algolia::Search::OperationIndexParams.new(operation: "copy", destination: tmp_index_name, scope: %w[settings synonyms rules])
+ Algolia::Search::OperationIndexParams.new(operation: Algolia::Search::OperationType::COPY, destination: tmp_index_name, scope: %w[settings synonyms rules])
).task_id
AlgoliaSearch.client.wait_for_task(index_name, task_id)
end
@@ -538,11 +538,11 @@ def algolia_set_settings(synchronous = false)
synonyms = s.delete("synonyms") || s.delete(:synonyms)
unless synonyms.nil? || synonyms.empty?
resp = AlgoliaSearch.client.save_synonyms(index_name,synonyms.map {|s| Algolia::Search::SynonymHit.new({object_id: s.join("-"), synonyms: s, type: "synonym"}) } )
- AlgoliaSearch.client.wait_for_task(index_name, resp.task_id) if synchronous
+ AlgoliaSearch.client.wait_for_task(index_name, resp.task_id) if synchronous || options[:synchronous]
end
resp = AlgoliaSearch.client.set_settings(index_name, Algolia::Search::IndexSettings.new(s))
- AlgoliaSearch.client.wait_for_task(index_name, resp.task_id) if synchronous
+ AlgoliaSearch.client.wait_for_task(index_name, resp.task_id) if synchronous || options[:synchronous]
end
end
From 1d81f478149ef3029370de7ccd82e91220933f72 Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Tue, 15 Oct 2024 15:21:22 +0200
Subject: [PATCH 36/40] feat: allow setting user agent
---
lib/algoliasearch/configuration.rb | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/lib/algoliasearch/configuration.rb b/lib/algoliasearch/configuration.rb
index 13aeaad..83020fb 100644
--- a/lib/algoliasearch/configuration.rb
+++ b/lib/algoliasearch/configuration.rb
@@ -1,9 +1,5 @@
module AlgoliaSearch
module Configuration
- REQUIRED_CONFIGURATION = {
- user_agent: "Algolia for Rails (#{AlgoliaSearch::VERSION}); Rails (#{defined?(::Rails::VERSION::STRING) ? ::Rails::VERSION::STRING : 'unknown'})",
- }
-
def initialize
@client = nil
end
@@ -13,11 +9,8 @@ def configuration
end
def configuration=(configuration)
- user_agent = [REQUIRED_CONFIGURATION[:user_agent], configuration[:append_to_user_agent]].compact.join('; ')
@@configuration = default_configuration
- .merge(configuration)
- .merge(REQUIRED_CONFIGURATION)
- .merge({ user_agent: user_agent })
+ .merge(configuration)
end
def client
@@ -29,7 +22,16 @@ def client
end
def setup_client
- @client = Algolia::SearchClient.create(@@configuration[:application_id], @@configuration[:api_key])
+ @client = Algolia::SearchClient.create(
+ @@configuration[:application_id],
+ @@configuration[:api_key],
+ {
+ user_agent_segments: [
+ "Algolia for Rails (#{AlgoliaSearch::VERSION})",
+ "Rails (#{defined?(::Rails::VERSION::STRING) ? ::Rails::VERSION::STRING : 'unknown'})",
+ @@configuration[:append_to_user_agent]
+ ].compact
+ })
end
def default_configuration
From 72998fd24f62c3bba08cc60f93d34ed5f29b372a Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Thu, 17 Oct 2024 18:29:18 +0200
Subject: [PATCH 37/40] pin version
---
Gemfile | 2 +-
algoliasearch-rails.gemspec | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/Gemfile b/Gemfile
index 83d5347..180e072 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,7 +1,7 @@
source "http://rubygems.org"
gem 'json', '>= 1.5.1'
-gem 'algolia', '>= 3.5.0'
+gem 'algolia', '>= 3.5.2'
if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
gem 'rubysl', '~> 2.0', :platform => :rbx
diff --git a/algoliasearch-rails.gemspec b/algoliasearch-rails.gemspec
index 1273172..e23ebb7 100644
--- a/algoliasearch-rails.gemspec
+++ b/algoliasearch-rails.gemspec
@@ -79,7 +79,7 @@ Gem::Specification.new do |s|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
s.add_runtime_dependency(%q, [">= 1.5.1"])
- s.add_runtime_dependency(%q, [">= 3.5.0"])
+ s.add_runtime_dependency(%q, [">= 3.5.2"])
s.add_development_dependency(%q, [">= 2.3.15"])
s.add_development_dependency(%q, [">= 0"])
s.add_development_dependency(%q, [">= 0"])
@@ -87,7 +87,7 @@ Gem::Specification.new do |s|
s.add_development_dependency "rdoc"
else
s.add_dependency(%q, [">= 1.5.1"])
- s.add_dependency(%q, [">= 3.5.0"])
+ s.add_dependency(%q, [">= 3.5.2"])
end
else
s.add_dependency(%q, [">= 1.5.1"])
From 5b3ceead349252cd951d1086aee416f1b57fd170 Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Thu, 17 Oct 2024 18:32:31 +0200
Subject: [PATCH 38/40] Update algoliasearch-rails.gemspec
---
algoliasearch-rails.gemspec | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/algoliasearch-rails.gemspec b/algoliasearch-rails.gemspec
index e23ebb7..64645a1 100644
--- a/algoliasearch-rails.gemspec
+++ b/algoliasearch-rails.gemspec
@@ -91,7 +91,7 @@ Gem::Specification.new do |s|
end
else
s.add_dependency(%q, [">= 1.5.1"])
- s.add_dependency(%q, ["< 3.0.0"])
+ s.add_dependency(%q, [">= 3.5.2"])
end
end
From 54e696fac4c1242a25b4befca4d5633ab526c1dc Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Fri, 18 Oct 2024 09:15:11 +0200
Subject: [PATCH 39/40] Update config.yml
---
.circleci/config.yml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index c6e59d5..ec150e8 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -74,12 +74,14 @@ workflows:
ci:
jobs:
- test:
+ name: "Ruby << matrix.version >> - Rails << matrix.rails-version >>"
matrix:
parameters:
version: [ '2.5', '2.6', '2.7', '3.0', '3.1' ]
rails-version: [ '6.0', '6.1' ]
sequel-version: [ '5.0' ]
- test:
+ name: "Ruby << matrix.version >> - Rails << matrix.rails-version >>"
matrix:
parameters:
version: ['3.0', '3.1']
From b23f7f2aba5286989e8b00a5efe199ccec28cf44 Mon Sep 17 00:00:00 2001
From: Devin Beeuwkes <46448173+DevinCodes@users.noreply.github.com>
Date: Fri, 18 Oct 2024 11:32:51 +0200
Subject: [PATCH 40/40] prep release
---
CHANGELOG.MD | 6 +++-
UPGRADING_TO_V3.MD | 66 ++++++++++++++++++++++++++++++++++++
lib/algoliasearch/version.rb | 2 +-
3 files changed, 72 insertions(+), 2 deletions(-)
create mode 100644 UPGRADING_TO_V3.MD
diff --git a/CHANGELOG.MD b/CHANGELOG.MD
index 6ac3967..27de238 100644
--- a/CHANGELOG.MD
+++ b/CHANGELOG.MD
@@ -1,6 +1,10 @@
# CHANGELOG
-## [Unreleased](https://github.com/algolia/algoliasearch-rails/compare/2.2.1...master)
+## [Unreleased](https://github.com/algolia/algoliasearch-rails/compare/3.0.0...master)
+
+## [3.0.0](https://github.com/algolia/algoliasearch-rails/compare/2.3.2...3.0.0)
+This new major version leverages the latest version of the Ruby Algolia API client. It also drops (official) support for Rails 5.x and Ruby versions older than 2.5
+For a list of known breaking changes, please refer to [the upgrade guide](./UPGRADING_TO_V3.MD)
## [2.3.2](https://github.com/algolia/algoliasearch-rails/compare/2.3.1...2.3.2)
### Added
diff --git a/UPGRADING_TO_V3.MD b/UPGRADING_TO_V3.MD
new file mode 100644
index 0000000..f94a479
--- /dev/null
+++ b/UPGRADING_TO_V3.MD
@@ -0,0 +1,66 @@
+Version 3 of the `algoliasearch-rails` gem replaces the Algolia API client version in use from version 2 to version 3.
+These versions of the API client differ significantly, so you likely need to make code changes when updating.
+We've tried keeping most of the changes internal, but there are still some breaking changes you need to be aware of when upgrading.
+
+If you encounter any breaking changes to the Rail integration that are not listed here, please open a Pull Request to add them to this list.
+
+## Breaking changes
+
+`algolia_ensure_init` (this method is protected and shouldn't be called manually, but we list it here anyways): the method no longer returns an initialized `index` object as this is not part of the new API client. The method now returns nothing, but it still ensures the index exists and applies settings if needed.
+
+---
+`Model.search`, `Model.raw_search`: response keys in the new API client are no longer strings, but are *always* symbols. For example:
+```ruby
+# Before
+results = Product.raw_search('shirt')
+p results['hits']
+
+# After
+results = Product.raw_search('shirt')
+p results[:hits]
+```
+---
+`Model.search_for_facet_values`: this no longer returns an array of hashes, but an array of objects of type `Algolia::Search::FacetHits`:
+```ruby
+# Before
+facets = Color.search_for_facet_values('short_name', 'bl', :query => 'black')
+puts facets.first['value']
+
+# After
+facets = Color.search_for_facet_values('short_name', 'bl', :query => 'black')
+facets.first.value
+```
+
+---
+`Model.index_name` takes an additional, optional parameter. You can use this if you want to get the name of one of your replica indices, which ensures the index naming takes configuration that modifies the index name into account.
+For example, if you have the `:per_environment` option set to true, it will automatically add the environment name in the index name.
+```ruby
+def Product
+ include AlgoliaSearch
+
+ algoliasearch({ per_environment: true }) do
+ add_replica 'Suits', per_environment: true do
+ # replica settings
+ end
+ end
+
+end
+main_index_name = Product.index_name
+replica_index_name = Product.index_name('Suits')
+```
+
+---
+`AlgoliaSearch::Configuration.client_opts`, `AlgoliaSearch::Configuration::REQUIRED_CONFIGURATION` and `AlgoliaSearch::SafeIndex` have been removed.
+If you need to configure the API client other than the ways that are provided now, it's recommended to set up an instance manually.
+
+---
+`Model.index` and `Model.algolia_index` have been removed, as there is no notion of an `Index` object in the new version of the API clients.
+Instead, you can use `Model.index_name` to get the name of the index to target, and use this on an instance of the API client directly.
+
+```ruby
+# Before
+res = Product.index.search('shoe')
+
+# After
+res = AlgoliaSearch.client.search_single_index(Product.index_name, { query: 'shoe' })
+```
diff --git a/lib/algoliasearch/version.rb b/lib/algoliasearch/version.rb
index 2748a12..bbc2c50 100644
--- a/lib/algoliasearch/version.rb
+++ b/lib/algoliasearch/version.rb
@@ -1,3 +1,3 @@
module AlgoliaSearch
- VERSION = '2.3.2'
+ VERSION = '3.0.0'
end