ActiveRecord Single Table Inheritance search bug #218

Closed
wants to merge 2 commits into
from
@@ -40,24 +40,25 @@ def results
else
return [] if hits.empty?
- type = @response['hits']['hits'].first['_type']
- raise NoMethodError, "You have tried to eager load the model instances, " +
+ records = {}
+ @response['hits']['hits'].group_by { |item| item['_type'] }.each do |type, items|
+ raise NoMethodError, "You have tried to eager load the model instances, " +
"but Tire cannot find the model class because " +
"document has no _type property." unless type
- begin
- klass = type.camelize.constantize
- rescue NameError => e
- raise NameError, "You have tried to eager load the model instances, but " +
- "Tire cannot find the model class '#{type.camelize}' " +
- "based on _type '#{type}'.", e.backtrace
+ begin
+ klass = type.camelize.constantize
+ rescue NameError => e
+ raise NameError, "You have tried to eager load the model instances, but " +
+ "Tire cannot find the model class '#{type.camelize}' " +
+ "based on _type '#{type}'.", e.backtrace
+ end
+ ids = items.map { |h| h['_id'] }
+ records[type] = @options[:load] === true ? klass.find(ids) : klass.find(ids, @options[:load])
end
- ids = @response['hits']['hits'].map { |h| h['_id'] }
- records = @options[:load] === true ? klass.find(ids) : klass.find(ids, @options[:load])
-
# Reorder records to preserve order from search results
- ids.map { |id| records.detect { |record| record.id.to_s == id.to_s } }
+ @response['hits']['hits'].map { |item| records[item['_type']].detect { |record| record.id.to_s == item['_id'].to_s } }
end
end
end
@@ -32,6 +32,10 @@ def setup
create_table :active_record_class_with_dynamic_index_names do |t|
t.string :title
end
+ create_table :sti_ancestors do |t|
+ t.string :title
+ t.string :type
+ end
end
end
@@ -352,6 +356,26 @@ module ::Rails; end
end
+ context 'with Single Table Inheritance' do
+ setup do
+ StiAncestor.create! :title => 'Ancestor text'
+ FirstStiDescendant.create! :title => 'Descendant text'
+ SecondStiDescendant.create! :title => 'Another Descendant text'
+ end
+
+ should 'load all STI descendants items' do
+ res = Tire.search('sti_ancestors', :load => true) do
+ query do
+ string 'Descendant'
+ end
+ end.results
+
+ assert_equal 2, res.length
+ assert_instance_of FirstStiDescendant, res[0]
+ assert_instance_of SecondStiDescendant, res[1]
+ end
+ end
+
end
end
@@ -78,3 +78,16 @@ class ActiveRecordClassWithDynamicIndexName < ActiveRecord::Base
"dynamic" + '_' + "index"
end
end
+
+class StiAncestor < ActiveRecord::Base
+ include Tire::Model::Search
+ include Tire::Model::Callbacks
+end
+
+class FirstStiDescendant < StiAncestor
+ index_name 'sti_ancestors'
+end
+
+class SecondStiDescendant < StiAncestor
+ index_name 'sti_ancestors'
+end