Skip to content

Commit

Permalink
Allowing for indexes on STI subclasses when parents are indexed as well.
Browse files Browse the repository at this point in the history
  • Loading branch information
pat committed Nov 27, 2009
1 parent ca79797 commit 3835780
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 17 deletions.
5 changes: 5 additions & 0 deletions features/sti_searching.feature
Expand Up @@ -12,3 +12,8 @@ Feature: Searching via STI model relationships
Given Sphinx is running
And I am searching on cats
Then I should get as many results as there are cats

Scenario: Searching across super and subclass indexes
Given Sphinx is running
When I search for "fantastic"
Then I should get 1 result
3 changes: 3 additions & 0 deletions features/support/db/fixtures/foxes.rb
@@ -0,0 +1,3 @@
%w( fantastic ).each do |name|
Fox.create :name => name
end
5 changes: 5 additions & 0 deletions features/support/models/fox.rb
@@ -0,0 +1,5 @@
class Fox < Animal
define_index do
indexes :name
end
end
7 changes: 7 additions & 0 deletions lib/thinking_sphinx.rb
Expand Up @@ -63,6 +63,13 @@ def self.version
def self.indexed_models
Thread.current[:thinking_sphinx_indexed_models] ||= []
end

def self.superclass_indexed_models
klasses = indexed_models.collect { |name| name.constantize }
klasses.reject { |klass|
klass.superclass.ancestors.any? { |ancestor| klasses.include?(ancestor) }
}.collect { |klass| klass.name }
end

def self.unique_id_expression(offset = nil)
"* #{indexed_models.size} + #{offset || 0}"
Expand Down
17 changes: 14 additions & 3 deletions lib/thinking_sphinx/active_record.rb
Expand Up @@ -127,6 +127,7 @@ def define_index(name = nil, &block)

unless ThinkingSphinx.indexed_models.include?(self.name)
ThinkingSphinx.indexed_models << self.name
ThinkingSphinx.indexed_models.sort!
end

add_sphinx_callbacks_and_extend(index.delta?)
Expand Down Expand Up @@ -166,11 +167,11 @@ def delta_index_names
sphinx_indexes.select(&:delta?).collect(&:delta_name)
end

def to_riddle(offset)
def to_riddle
sphinx_database_adapter.setup

local_sphinx_indexes.collect { |index|
index.to_riddle(offset)
index.to_riddle(sphinx_offset)
}.flatten
end

Expand All @@ -195,6 +196,10 @@ def delete_in_index(index, document_id)
)
end

def sphinx_offset
ThinkingSphinx.superclass_indexed_models.index eldest_indexed_ancestor
end

private

def local_sphinx_indexes
Expand All @@ -219,6 +224,12 @@ def add_sphinx_callbacks_and_extend(delta = false)
after_commit :index_delta
end
end

def eldest_indexed_ancestor
ancestors.reverse.detect { |ancestor|
ThinkingSphinx.indexed_models.include?(ancestor.name)
}.name
end
end

def in_index?(suffix)
Expand Down Expand Up @@ -263,7 +274,7 @@ def primary_key_for_sphinx

def sphinx_document_id
primary_key_for_sphinx * ThinkingSphinx.indexed_models.size +
ThinkingSphinx.indexed_models.index(self.class.source_of_sphinx_index.name)
self.class.sphinx_offset
end

private
Expand Down
4 changes: 2 additions & 2 deletions lib/thinking_sphinx/configuration.rb
Expand Up @@ -147,8 +147,8 @@ def build(file_path=nil)

@configuration.indexes.clear

ThinkingSphinx.indexed_models.each_with_index do |model, model_index|
@configuration.indexes.concat model.constantize.to_riddle(model_index)
ThinkingSphinx.indexed_models.each do |model|
@configuration.indexes.concat model.constantize.to_riddle
end

open(file_path, "w") do |file|
Expand Down
35 changes: 23 additions & 12 deletions spec/thinking_sphinx/active_record_spec.rb
Expand Up @@ -365,19 +365,9 @@
it "should return values with the expected offset" do
person = Person.find(:first)
model_count = ThinkingSphinx.indexed_models.length
offset = ThinkingSphinx.indexed_models.index("Person")
Person.stub!(:sphinx_offset => 3)

(person.id * model_count + offset).should == person.sphinx_document_id

alpha = Alpha.find(:first)
offset = ThinkingSphinx.indexed_models.index("Alpha")

(alpha.id * model_count + offset).should == alpha.sphinx_document_id

beta = Beta.find(:first)
offset = ThinkingSphinx.indexed_models.index("Beta")

(beta.id * model_count + offset).should == beta.sphinx_document_id
(person.id * model_count + 3).should == person.sphinx_document_id
end
end

Expand Down Expand Up @@ -510,4 +500,25 @@
Alpha.delta_index_names.should == ['foo_delta']
end
end

describe '.sphinx_offset' do
it "should return the index of the model's name in all known indexed models" do
ThinkingSphinx.stub!(:indexed_models => ['Alpha', 'Beta'])

Alpha.sphinx_offset.should == 0
Beta.sphinx_offset.should == 1
end

it "should ignore classes that have indexed superclasses" do
ThinkingSphinx.stub!(:indexed_models => ['Alpha', 'Parent', 'Person'])

Person.sphinx_offset.should == 1
end

it "should respect first known indexed parents" do
ThinkingSphinx.stub!(:indexed_models => ['Alpha', 'Parent', 'Person'])

Parent.sphinx_offset.should == 1
end
end
end
14 changes: 14 additions & 0 deletions spec/thinking_sphinx_spec.rb
Expand Up @@ -91,6 +91,20 @@
end
end

describe '.superclass_indexed_models' do
it "should return indexed model names" do
ThinkingSphinx.stub!(:indexed_models => ['Alpha', 'Beta'])

ThinkingSphinx.superclass_indexed_models.should == ['Alpha', 'Beta']
end

it "should not include classes which have indexed superclasses" do
ThinkingSphinx.stub!(:indexed_models => ['Parent', 'Person'])

ThinkingSphinx.superclass_indexed_models.should == ['Person']
end
end

describe "use_group_by_shortcut? method" do
before :each do
adapter = defined?(JRUBY_VERSION) ? :JdbcAdapter : :MysqlAdapter
Expand Down

0 comments on commit 3835780

Please sign in to comment.