Skip to content

Commit

Permalink
feat: Processor for actions on AR instances.
Browse files Browse the repository at this point in the history
Prompted by discussion in #1215, this provides a direct interface to
perform index-related operations on an ActiveRecord index.

    processor = ThinkingSphinx::Processor.new(instance)
    processor.delete
    processor.upsert # real-time indices only
  • Loading branch information
pat committed Feb 27, 2022
1 parent 5b44acc commit f6657c9
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 12 deletions.
1 change: 1 addition & 0 deletions lib/thinking_sphinx.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ module Subscribers; end
require 'thinking_sphinx/masks'
require 'thinking_sphinx/middlewares'
require 'thinking_sphinx/panes'
require 'thinking_sphinx/processor'
require 'thinking_sphinx/query'
require 'thinking_sphinx/rake_interface'
require 'thinking_sphinx/scopes'
Expand Down
14 changes: 2 additions & 12 deletions lib/thinking_sphinx/active_record/callbacks/delete_callbacks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,8 @@ def after_rollback
private

def delete_from_sphinx
return if ThinkingSphinx::Callbacks.suspended? || instance.new_record?
return if ThinkingSphinx::Callbacks.suspended?

indices.each { |index|
ThinkingSphinx::Deletion.perform(
index, instance.public_send(index.primary_key)
)
}
end

def indices
ThinkingSphinx::Configuration.instance.index_set_class.new(
:instances => [instance], :classes => [instance.class]
).to_a
ThinkingSphinx::Processor.new(instance).delete
end
end
37 changes: 37 additions & 0 deletions lib/thinking_sphinx/processor.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# frozen_string_literal: true

class ThinkingSphinx::Processor
def initialize(instance)
@instance = instance
end

def delete
return if instance.new_record?

indices.each { |index|
ThinkingSphinx::Deletion.perform(
index, instance.public_send(index.primary_key)
)
}
end

def upsert
real_time_indices.each do |index|
ThinkingSphinx::RealTime::Transcriber.new(index).copy instance
end
end

private

attr_reader :instance

def indices
ThinkingSphinx::Configuration.instance.index_set_class.new(
:instances => [instance], :classes => [instance.class]
).to_a
end

def real_time_indices
indices.select { |index| index.is_a? ThinkingSphinx::RealTime::Index }
end
end
25 changes: 25 additions & 0 deletions spec/acceptance/real_time_updates_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,29 @@
expect(Admin::Person.search('Death').to_a).to be_empty
expect(Admin::Person.search('Mort').to_a).to eq([person])
end

it "can use a direct interface for processing records" do
Admin::Person.connection.execute <<~SQL
INSERT INTO admin_people (name, created_at, updated_at)
VALUES ('Pat', now(), now());
SQL

expect(Admin::Person.search('Pat').to_a).to be_empty

instance = Admin::Person.find_by(:name => 'Pat')
ThinkingSphinx::Processor.new(instance).upsert

expect(Admin::Person.search('Pat').to_a).to eq([instance])

Admin::Person.connection.execute <<~SQL
UPDATE admin_people SET name = 'Patrick' WHERE name = 'Pat';
SQL

expect(Admin::Person.search('Patrick').to_a).to be_empty

instance.reload
ThinkingSphinx::Processor.new(instance).upsert

expect(Admin::Person.search('Patrick').to_a).to eq([instance])
end
end

0 comments on commit f6657c9

Please sign in to comment.