diff --git a/lib/thinking_sphinx/processor.rb b/lib/thinking_sphinx/processor.rb index b2ad823d..7e1e8ded 100644 --- a/lib/thinking_sphinx/processor.rb +++ b/lib/thinking_sphinx/processor.rb @@ -14,7 +14,7 @@ def delete indices.each { |index| ThinkingSphinx::Deletion.perform( - index, id || instance.public_send(index.primary_key) + index, id ) } end @@ -25,9 +25,21 @@ def upsert end end + def stage + real_time_indices.each do |index| + found = index.scope.find_by(model.primary_key => id) + + if found + ThinkingSphinx::RealTime::Transcriber.new(index).copy found + else + ThinkingSphinx::Deletion.perform(index, id) + end + end + end + private - attr_reader :instance, :model, :id + attr_reader :instance, :model def indices ThinkingSphinx::Configuration.instance.index_set_class.new( @@ -39,6 +51,10 @@ def loaded_instance @loaded_instance ||= instance || model.find(id) end + def id + @id ||= instance.public_send(instance.class.primary_key) + end + def real_time_indices indices.select { |index| index.is_a? ThinkingSphinx::RealTime::Index } end diff --git a/spec/acceptance/real_time_updates_spec.rb b/spec/acceptance/real_time_updates_spec.rb index 7a51c91c..f0803408 100644 --- a/spec/acceptance/real_time_updates_spec.rb +++ b/spec/acceptance/real_time_updates_spec.rb @@ -28,7 +28,7 @@ expect(Admin::Person.search('Mort').to_a).to eq([person]) end - it "can use a direct interface for processing records" do + it "can use direct interface for upserting records" do Admin::Person.connection.execute <<~SQL INSERT INTO admin_people (name, created_at, updated_at) VALUES ('Pat', now(), now()); @@ -52,4 +52,44 @@ expect(Admin::Person.search('Patrick').to_a).to eq([instance]) end + + it "can use direct interface for processing records outside scope" do + Article.connection.execute <<~SQL + INSERT INTO articles (title, published, created_at, updated_at) + VALUES ('Nice Title', TRUE, now(), now()); + SQL + + article = Article.last + + ThinkingSphinx::Processor.new(model: article.class, id: article.id).stage + + expect(ThinkingSphinx.search('Nice', :indices => ["published_articles_core"])).to include(article) + + Article.connection.execute <<~SQL + UPDATE articles SET published = FALSE WHERE title = 'Nice Title'; + SQL + ThinkingSphinx::Processor.new(model: article.class, id: article.id).stage + + expect(ThinkingSphinx.search('Nice', :indices => ["published_articles_core"])).to be_empty + end + + it "can use direct interface for processing deleted records" do + Article.connection.execute <<~SQL + INSERT INTO articles (title, published, created_at, updated_at) + VALUES ('Nice Title', TRUE, now(), now()); + SQL + + article = Article.last + ThinkingSphinx::Processor.new(:instance => article).stage + + expect(ThinkingSphinx.search('Nice', :indices => ["published_articles_core"])).to include(article) + + Article.connection.execute <<~SQL + DELETE FROM articles where title = 'Nice Title'; + SQL + + ThinkingSphinx::Processor.new(:instance => article).stage + + expect(ThinkingSphinx.search('Nice', :indices => ["published_articles_core"])).to be_empty + end end diff --git a/spec/internal/app/indices/article_index.rb b/spec/internal/app/indices/article_index.rb index c8f611f1..a0c45621 100644 --- a/spec/internal/app/indices/article_index.rb +++ b/spec/internal/app/indices/article_index.rb @@ -23,3 +23,9 @@ set_property :morphology => 'stem_en' end + +ThinkingSphinx::Index.define :article, :name => :published_articles, :with => :real_time do + indexes title, content + + scope { Article.where :published => true } +end