thinking-sphinx 2.0.2 → 2.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.textile CHANGED
@@ -197,3 +197,9 @@ Since I first released this library, there's been quite a few people who have su
197
197
  * Robert Glaser
198
198
  * Brenton Fletcher
199
199
  * Paul Schyska
200
+ * Kirill Maximov
201
+ * Hans Hasselberg
202
+ * Robert Stern
203
+ * George Anderson
204
+ * Greg Weber
205
+ * Javier Ramírez
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.2
1
+ 2.0.3
@@ -36,7 +36,7 @@ Feature: Update attributes directly to Sphinx
36
36
  And I filter by 18 on value
37
37
  Then I should get 1 result
38
38
 
39
- When I search for the document id of beta eight in the beta_delta index
39
+ When I search for the document id of beta eight in the secondary_beta_delta index
40
40
  Then it should not exist
41
41
 
42
42
  Scenario: Updating attributes in a delta index
@@ -48,7 +48,7 @@ Feature: Update attributes directly to Sphinx
48
48
  And I wait for Sphinx to catch up
49
49
 
50
50
  When I filter by 19 on value
51
- And I use index beta_delta
51
+ And I use index secondary_beta_delta
52
52
  Then I should get 1 result
53
53
 
54
54
  Scenario: Updating attributes in a delta index with deltas disabled
@@ -61,7 +61,7 @@ Feature: Update attributes directly to Sphinx
61
61
  And I wait for Sphinx to catch up
62
62
 
63
63
  When I filter by 21 on value
64
- And I use index beta_delta
64
+ And I use index secondary_beta_delta
65
65
  Then I should get 1 result
66
66
  And I enable delta updates
67
67
 
@@ -31,12 +31,12 @@ Feature: Keeping Sphinx in line with model changes when requested
31
31
  When I search for one
32
32
  Then I should get 1 result
33
33
 
34
- When I change the name of beta one to eleven
34
+ When I change the name of beta one to eleventeen
35
35
  And I wait for Sphinx to catch up
36
36
  And I search for one
37
37
  Then I should get 0 results
38
38
 
39
- When I search for eleven
39
+ When I search for eleventeen
40
40
  Then I should get 1 result
41
41
 
42
42
  Scenario: Returning new records if there's a delta
@@ -63,7 +63,9 @@ Feature: Keeping Sphinx in line with model changes when requested
63
63
 
64
64
  When I search for the document id of beta five in the beta_core index
65
65
  Then it should exist if using Rails 2.1 or newer
66
- When I search for the document id of beta five in the beta_delta index
66
+ When I search for the document id of beta five in the secondary_beta_core index
67
+ Then it should exist if using Rails 2.1 or newer
68
+ When I search for the document id of beta five in the secondary_beta_delta index
67
69
  Then it should not exist if using Rails 2.1 or newer
68
70
 
69
71
  Scenario: Handling edits with a delta when Sphinx isn't running
@@ -2,6 +2,11 @@ class Beta < ActiveRecord::Base
2
2
  define_index do
3
3
  indexes :name, :sortable => true, :facet => true
4
4
  has value
5
+ end
6
+
7
+ define_index 'secondary_beta' do
8
+ indexes :name, :sortable => true, :facet => true
9
+ has value
5
10
 
6
11
  set_property :delta => true
7
12
  end
@@ -17,4 +17,15 @@ class Developer < ActiveRecord::Base
17
17
 
18
18
  group_by 'city'
19
19
  end
20
+
21
+ define_index 'alternate' do
22
+ indexes "'foo'", :as => :foo
23
+
24
+ has age, :facet => true
25
+ has tags(:id), :as => :tag_ids, :facet => true
26
+
27
+ facet "LOWER(city)", :as => :city, :type => :string, :value => :city
28
+
29
+ group_by 'city'
30
+ end
20
31
  end
@@ -1,3 +1,4 @@
1
+ require 'thread'
1
2
  require 'active_record'
2
3
  require 'yaml'
3
4
  require 'riddle'
@@ -2,6 +2,7 @@ require 'thinking_sphinx/active_record/attribute_updates'
2
2
  require 'thinking_sphinx/active_record/delta'
3
3
  require 'thinking_sphinx/active_record/has_many_association'
4
4
  require 'thinking_sphinx/active_record/log_subscriber'
5
+ require 'thinking_sphinx/active_record/has_many_association_with_scopes'
5
6
  require 'thinking_sphinx/active_record/scopes'
6
7
 
7
8
  module ThinkingSphinx
@@ -24,7 +25,18 @@ module ThinkingSphinx
24
25
  end
25
26
 
26
27
  def primary_key_for_sphinx
27
- @sphinx_primary_key_attribute || primary_key
28
+ if custom_primary_key_for_sphinx?
29
+ @sphinx_primary_key_attribute || superclass.primary_key_for_sphinx
30
+ else
31
+ primary_key
32
+ end
33
+ end
34
+
35
+ def custom_primary_key_for_sphinx?
36
+ (
37
+ superclass.respond_to?(:custom_primary_key_for_sphinx?) &&
38
+ superclass.custom_primary_key_for_sphinx?
39
+ ) || !@sphinx_primary_key_attribute.nil?
28
40
  end
29
41
 
30
42
  def sphinx_index_options
@@ -46,8 +58,7 @@ module ThinkingSphinx
46
58
  end
47
59
 
48
60
  def sphinx_database_adapter
49
- @sphinx_database_adapter ||=
50
- ThinkingSphinx::AbstractAdapter.detect(self)
61
+ ThinkingSphinx::AbstractAdapter.detect(self)
51
62
  end
52
63
 
53
64
  def sphinx_name
@@ -315,22 +326,12 @@ module ThinkingSphinx
315
326
  attr_accessor :sphinx_attributes
316
327
  attr_accessor :matching_fields
317
328
 
318
- def in_index?(suffix)
319
- self.class.search_for_id self.sphinx_document_id, sphinx_index_name(suffix)
320
- end
321
-
322
- def in_core_index?
323
- in_index? "core"
324
- end
325
-
326
- def in_delta_index?
327
- in_index? "delta"
328
- end
329
-
330
- def in_both_indexes?
331
- in_core_index? && in_delta_index?
329
+ def in_index?(index)
330
+ self.class.search_for_id self.sphinx_document_id, index
331
+ rescue Riddle::ResponseError
332
+ true
332
333
  end
333
-
334
+
334
335
  def toggle_deleted
335
336
  return unless ThinkingSphinx.updates_enabled?
336
337
 
@@ -43,7 +43,7 @@ module ThinkingSphinx
43
43
  config = ThinkingSphinx::Configuration.instance
44
44
  config.client.update index_name, attribute_names, {
45
45
  sphinx_document_id => attribute_values
46
- } if self.class.search_for_id(sphinx_document_id, index_name)
46
+ } if in_index?(index_name)
47
47
  rescue Riddle::ConnectionError, ThinkingSphinx::SphinxError
48
48
  # Not the end of the world if Sphinx isn't running.
49
49
  end
@@ -16,30 +16,34 @@ module ThinkingSphinx
16
16
  # if running in the test environment.
17
17
  #
18
18
  def index_delta(instance = nil)
19
- delta_object.index(self, instance)
19
+ delta_objects.each { |obj| obj.index(self, instance) }
20
20
  end
21
21
 
22
- def delta_object
23
- self.sphinx_indexes.first.delta_object
22
+ def delta_objects
23
+ self.sphinx_indexes.collect(&:delta_object).compact
24
24
  end
25
25
  end
26
26
 
27
27
  def toggled_delta?
28
- self.class.delta_object.toggled(self)
28
+ self.class.delta_objects.any? { |obj| obj.toggled(self) }
29
29
  end
30
30
 
31
31
  private
32
32
 
33
33
  # Set the delta value for the model to be true.
34
34
  def toggle_delta
35
- self.class.delta_object.toggle(self) if should_toggle_delta?
35
+ self.class.delta_objects.each { |obj|
36
+ obj.toggle(self)
37
+ } if should_toggle_delta?
36
38
  end
37
39
 
38
40
  # Build the delta index for the related model. This won't be called
39
41
  # if running in the test environment.
40
42
  #
41
43
  def index_delta
42
- self.class.index_delta(self) if self.class.delta_object.toggled(self)
44
+ self.class.index_delta(self) if self.class.delta_objects.any? { |obj|
45
+ obj.toggled(self)
46
+ }
43
47
  end
44
48
 
45
49
  def should_toggle_delta?
@@ -9,17 +9,7 @@ module ThinkingSphinx
9
9
  args << options
10
10
  @reflection.klass.search(*args)
11
11
  end
12
-
13
- def method_missing(method, *args, &block)
14
- if responds_to_scope(method)
15
- @reflection.klass.
16
- search(:with => default_filter).
17
- send(method, *args, &block)
18
- else
19
- super
20
- end
21
- end
22
-
12
+
23
13
  private
24
14
 
25
15
  def attribute_for_foreign_key
@@ -41,11 +31,6 @@ module ThinkingSphinx
41
31
  def default_filter
42
32
  {attribute_for_foreign_key.unique_name => @owner.id}
43
33
  end
44
-
45
- def responds_to_scope(scope)
46
- @reflection.klass.respond_to?(:sphinx_scopes) &&
47
- @reflection.klass.sphinx_scopes.include?(scope)
48
- end
49
34
  end
50
35
  end
51
36
  end
@@ -0,0 +1,21 @@
1
+ module ThinkingSphinx
2
+ module ActiveRecord
3
+ module HasManyAssociationWithScopes
4
+ def method_missing(method, *args, &block)
5
+ if responds_to_scope(method)
6
+ @reflection.klass.
7
+ search(:with => default_filter).
8
+ send(method, *args, &block)
9
+ else
10
+ super
11
+ end
12
+ end
13
+
14
+ private
15
+ def responds_to_scope(scope)
16
+ @reflection.klass.respond_to?(:sphinx_scopes) &&
17
+ @reflection.klass.sphinx_scopes.include?(scope)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -17,6 +17,7 @@ module ThinkingSphinx
17
17
  # The scope is automatically applied when the search method is called. It
18
18
  # will only be applied if it is an existing sphinx_scope.
19
19
  def default_sphinx_scope(sphinx_scope_name)
20
+ add_sphinx_scopes_support_to_has_many_associations
20
21
  @default_sphinx_scope = sphinx_scope_name
21
22
  end
22
23
 
@@ -43,6 +44,8 @@ module ThinkingSphinx
43
44
  # @articles = Article.latest_first.search 'pancakes'
44
45
  #
45
46
  def sphinx_scope(method, &block)
47
+ add_sphinx_scopes_support_to_has_many_associations
48
+
46
49
  @sphinx_scopes ||= []
47
50
  @sphinx_scopes << method
48
51
 
@@ -76,6 +79,14 @@ module ThinkingSphinx
76
79
 
77
80
  sphinx_scopes.clear
78
81
  end
82
+
83
+ def add_sphinx_scopes_support_to_has_many_associations
84
+ scope_mixin = ::ThinkingSphinx::ActiveRecord::HasManyAssociationWithScopes
85
+
86
+ ::ActiveRecord::Associations::HasManyAssociation.send(:include, scope_mixin)
87
+ ::ActiveRecord::Associations::HasManyThroughAssociation.send(:include, scope_mixin)
88
+ end
89
+
79
90
  end
80
91
  end
81
92
  end
@@ -117,6 +117,7 @@ module ThinkingSphinx
117
117
  DECLARE tmp bigint;
118
118
  DECLARE i int;
119
119
  DECLARE j int;
120
+ DECLARE byte_length int;
120
121
  DECLARE word_array bytea;
121
122
  BEGIN
122
123
  IF COALESCE(word, '') = '' THEN
@@ -125,6 +126,7 @@ module ThinkingSphinx
125
126
 
126
127
  i = 0;
127
128
  tmp = 4294967295;
129
+ byte_length = bit_length(word) / 8;
128
130
  word_array = decode(replace(word, E'\\\\', E'\\\\\\\\'), 'escape');
129
131
  LOOP
130
132
  tmp = (tmp # get_byte(word_array, i))::bigint;
@@ -137,7 +139,7 @@ module ThinkingSphinx
137
139
  EXIT;
138
140
  END IF;
139
141
  END LOOP;
140
- IF i >= char_length(word) THEN
142
+ IF i >= byte_length THEN
141
143
  EXIT;
142
144
  END IF;
143
145
  END LOOP;
@@ -5,9 +5,12 @@ module ThinkingSphinx
5
5
  case version
6
6
  when '0.9.8', '0.9.9'
7
7
  require "riddle/#{version}"
8
- when '1.10-beta', '1.10-id64-beta'
8
+ when '1.10-beta', '1.10-id64-beta', '1.10-dev'
9
9
  require 'riddle/1.10'
10
10
  else
11
+ unless version.nil? or version.empty?
12
+ STDERR.puts "Unsupported version: #{version}"
13
+ end
11
14
  STDERR.puts %Q{
12
15
  Sphinx cannot be found on your system. You may need to configure the following
13
16
  settings in your config/sphinx.yml file:
@@ -6,7 +6,7 @@ end
6
6
 
7
7
  module SearchAsArray
8
8
  def ===(object)
9
- object.is_a?(ThinkingSphinx::Search) || super
9
+ (ThinkingSphinx::Search === object) || super
10
10
  end
11
11
  end
12
12
 
@@ -30,31 +30,31 @@ module ThinkingSphinx
30
30
  # Deprecated. Use ThinkingSphinx.search
31
31
  def self.search(*args)
32
32
  warn 'ThinkingSphinx::Search.search is deprecated. Please use ThinkingSphinx.search instead.'
33
- ThinkingSphinx.search *args
33
+ ThinkingSphinx.search(*args)
34
34
  end
35
35
 
36
36
  # Deprecated. Use ThinkingSphinx.search_for_ids
37
37
  def self.search_for_ids(*args)
38
38
  warn 'ThinkingSphinx::Search.search_for_ids is deprecated. Please use ThinkingSphinx.search_for_ids instead.'
39
- ThinkingSphinx.search_for_ids *args
39
+ ThinkingSphinx.search_for_ids(*args)
40
40
  end
41
41
 
42
42
  # Deprecated. Use ThinkingSphinx.search_for_ids
43
43
  def self.search_for_id(*args)
44
44
  warn 'ThinkingSphinx::Search.search_for_id is deprecated. Please use ThinkingSphinx.search_for_id instead.'
45
- ThinkingSphinx.search_for_id *args
45
+ ThinkingSphinx.search_for_id(*args)
46
46
  end
47
47
 
48
48
  # Deprecated. Use ThinkingSphinx.count
49
49
  def self.count(*args)
50
50
  warn 'ThinkingSphinx::Search.count is deprecated. Please use ThinkingSphinx.count instead.'
51
- ThinkingSphinx.count *args
51
+ ThinkingSphinx.count(*args)
52
52
  end
53
53
 
54
54
  # Deprecated. Use ThinkingSphinx.facets
55
55
  def self.facets(*args)
56
56
  warn 'ThinkingSphinx::Search.facets is deprecated. Please use ThinkingSphinx.facets instead.'
57
- ThinkingSphinx.facets *args
57
+ ThinkingSphinx.facets(*args)
58
58
  end
59
59
 
60
60
  def self.warn(message)
@@ -202,6 +202,12 @@ module ThinkingSphinx
202
202
  @options[:page].blank? ? 1 : @options[:page].to_i
203
203
  end
204
204
 
205
+ # Kaminari support
206
+ def page(page_number)
207
+ @options[:page] = page_number
208
+ self
209
+ end
210
+
205
211
  # The next page number of the result set. If there are no more pages
206
212
  # available, nil is returned.
207
213
  #
@@ -230,6 +236,14 @@ module ThinkingSphinx
230
236
  @options[:limit] ||= 20
231
237
  @options[:limit].to_i
232
238
  end
239
+ # Kaminari support
240
+ alias_method :limit_value, :per_page
241
+
242
+ # Kaminari support
243
+ def per(limit)
244
+ @options[:limit] = limit
245
+ self
246
+ end
233
247
 
234
248
  # The total number of pages available if the results are paginated.
235
249
  #
@@ -241,8 +255,9 @@ module ThinkingSphinx
241
255
 
242
256
  @total_pages ||= (@results[:total] / per_page.to_f).ceil
243
257
  end
244
- # Compatibility with older versions of will_paginate
258
+ # Compatibility with kaminari and older versions of will_paginate
245
259
  alias_method :page_count, :total_pages
260
+ alias_method :num_pages, :total_pages
246
261
 
247
262
  # Query time taken
248
263
  #
@@ -318,7 +333,7 @@ module ThinkingSphinx
318
333
  {
319
334
  :docs => [string.to_s],
320
335
  :words => results[:words].keys.join(' '),
321
- :index => options[:index] || "#{model.source_of_sphinx_index.sphinx_name}_core"
336
+ :index => options[:index] || "#{model.core_index_names.first}"
322
337
  }.merge(options[:excerpt_options] || {})
323
338
  ).first
324
339
  end
@@ -343,7 +358,7 @@ module ThinkingSphinx
343
358
  merge_search self, args, options
344
359
  args << options
345
360
 
346
- ThinkingSphinx::FacetSearch.new *args
361
+ ThinkingSphinx::FacetSearch.new(*args)
347
362
  end
348
363
 
349
364
  def client
@@ -363,16 +378,7 @@ module ThinkingSphinx
363
378
  @populated = true
364
379
  @results = results
365
380
 
366
- if options[:ids_only]
367
- replace @results[:matches].collect { |match|
368
- match[:attributes]["sphinx_internal_id"]
369
- }
370
- else
371
- replace instances_from_matches
372
- add_excerpter
373
- add_sphinx_attributes
374
- add_matching_fields if client.rank_mode == :fieldmask
375
- end
381
+ compose_results
376
382
  end
377
383
 
378
384
  private
@@ -403,18 +409,44 @@ module ThinkingSphinx
403
409
  raise ThinkingSphinx::ConnectionError,
404
410
  'Connection to Sphinx Daemon (searchd) failed.'
405
411
  end
406
-
407
- if options[:ids_only]
408
- replace @results[:matches].collect { |match|
409
- match[:attributes]["sphinx_internal_id"]
410
- }
412
+
413
+ compose_results
414
+ end
415
+ end
416
+
417
+ def compose_results
418
+ if options[:ids_only]
419
+ compose_ids_results
420
+ elsif options[:only]
421
+ compose_only_results
422
+ else
423
+ replace instances_from_matches
424
+ add_excerpter
425
+ add_sphinx_attributes
426
+ add_matching_fields if client.rank_mode == :fieldmask
427
+ end
428
+ end
429
+
430
+ def compose_ids_results
431
+ replace @results[:matches].collect { |match|
432
+ match[:attributes]['sphinx_internal_id']
433
+ }
434
+ end
435
+
436
+ def compose_only_results
437
+ replace @results[:matches].collect { |match|
438
+ case only = options[:only]
439
+ when String, Symbol
440
+ match[:attributes][only.to_s]
441
+ when Array
442
+ only.inject({}) do |hash, attribute|
443
+ hash[attribute.to_sym] = match[:attributes][attribute.to_s]
444
+ hash
445
+ end
411
446
  else
412
- replace instances_from_matches
413
- add_excerpter
414
- add_sphinx_attributes
415
- add_matching_fields if client.rank_mode == :fieldmask
447
+ raise "Unexpected object for :only argument. String or Array is expected, #{only.class} was received."
416
448
  end
417
- end
449
+ }
418
450
  end
419
451
 
420
452
  def add_excerpter
@@ -908,7 +940,7 @@ module ThinkingSphinx
908
940
  end
909
941
 
910
942
  def scoped_count
911
- return self.total_entries if @options[:ids_only]
943
+ return self.total_entries if(@options[:ids_only] || @options[:only])
912
944
 
913
945
  @options[:ids_only] = true
914
946
  results_count = self.total_entries
@@ -70,7 +70,7 @@ describe "ThinkingSphinx::ActiveRecord::Delta" do
70
70
  ThinkingSphinx.deltas_enabled = true
71
71
  ThinkingSphinx.updates_enabled = true
72
72
  ThinkingSphinx.stub!(:sphinx_running? => true)
73
- Person.delta_object.stub!(:` => "", :toggled => true)
73
+ Person.delta_objects.first.stub!(:` => "", :toggled => true)
74
74
 
75
75
  @person = Person.new
76
76
  Person.stub!(:search_for_id => false)
@@ -234,50 +234,6 @@ describe ThinkingSphinx::ActiveRecord do
234
234
  Beta.sphinx_indexes.length.should == 1
235
235
  end
236
236
  end
237
-
238
- describe "index methods" do
239
- before(:all) do
240
- @person = Person.find(:first)
241
- end
242
-
243
- describe "in_both_indexes?" do
244
- it "should return true if in core and delta indexes" do
245
- @person.should_receive(:in_core_index?).and_return(true)
246
- @person.should_receive(:in_delta_index?).and_return(true)
247
- @person.in_both_indexes?.should be_true
248
- end
249
-
250
- it "should return false if in one index and not the other" do
251
- @person.should_receive(:in_core_index?).and_return(true)
252
- @person.should_receive(:in_delta_index?).and_return(false)
253
- @person.in_both_indexes?.should be_false
254
- end
255
- end
256
-
257
- describe "in_core_index?" do
258
- it "should call in_index? with core" do
259
- @person.should_receive(:in_index?).with('core')
260
- @person.in_core_index?
261
- end
262
- end
263
-
264
- describe "in_delta_index?" do
265
- it "should call in_index? with delta" do
266
- @person.should_receive(:in_index?).with('delta')
267
- @person.in_delta_index?
268
- end
269
- end
270
-
271
- describe "in_index?" do
272
- it "should return true if in the specified index" do
273
- @person.should_receive(:sphinx_document_id).and_return(1)
274
- @person.should_receive(:sphinx_index_name).and_return('person_core')
275
- Person.should_receive(:search_for_id).with(1, 'person_core').and_return(true)
276
-
277
- @person.in_index?('core').should be_true
278
- end
279
- end
280
- end
281
237
 
282
238
  describe '.source_of_sphinx_index' do
283
239
  it "should return self if model defines an index" do
@@ -450,6 +406,12 @@ describe ThinkingSphinx::ActiveRecord do
450
406
  @person.stub!(:id => 'unique_hash')
451
407
  @person.primary_key_for_sphinx.should == id
452
408
  end
409
+
410
+ it "should be inherited by subclasses" do
411
+ Person.set_sphinx_primary_key :first_name
412
+ Parent.superclass.custom_primary_key_for_sphinx?
413
+ Parent.primary_key_for_sphinx.should == Person.primary_key_for_sphinx
414
+ end
453
415
  end
454
416
 
455
417
  describe '.sphinx_index_names' do
@@ -39,7 +39,7 @@ describe ThinkingSphinx::AutoVersion do
39
39
  end
40
40
 
41
41
  it "should output a warning if the detected version is something else" do
42
- STDERR.should_receive(:puts)
42
+ STDERR.should_receive(:puts).twice
43
43
 
44
44
  @config.stub!(:version => '0.9.7')
45
45
  ThinkingSphinx::AutoVersion.detect
@@ -98,6 +98,14 @@ describe ThinkingSphinx::FacetSearch do
98
98
  :classes => [Person], :facets => :state
99
99
  )
100
100
  end
101
+
102
+ it "should handle multiple facets" do
103
+ ThinkingSphinx.should_receive(:search).twice.and_return(search)
104
+
105
+ ThinkingSphinx::FacetSearch.new(
106
+ :classes => [Person], :facets => [:state, :city]
107
+ )
108
+ end
101
109
  end
102
110
 
103
111
  describe "empty result set for attributes" do
@@ -877,6 +877,36 @@ describe ThinkingSphinx::Search do
877
877
  end
878
878
  end
879
879
 
880
+ describe ':only option' do
881
+ it "returns the requested attribute as an array" do
882
+ ThinkingSphinx::Search.new(:only => :class_crc).first.
883
+ should == Alpha.to_crc32
884
+ end
885
+
886
+ it "returns multiple attributes as hashes with values" do
887
+ ThinkingSphinx::Search.new(
888
+ :only => [:class_crc, :sphinx_internal_id]
889
+ ).first.should == {
890
+ :class_crc => Alpha.to_crc32,
891
+ :sphinx_internal_id => @alpha_a.id
892
+ }
893
+ end
894
+
895
+ it "handles strings for a single attribute name" do
896
+ ThinkingSphinx::Search.new(:only => 'class_crc').first.
897
+ should == Alpha.to_crc32
898
+ end
899
+
900
+ it "handles strings for multiple attribute names" do
901
+ ThinkingSphinx::Search.new(
902
+ :only => ['class_crc', 'sphinx_internal_id']
903
+ ).first.should == {
904
+ :class_crc => Alpha.to_crc32,
905
+ :sphinx_internal_id => @alpha_a.id
906
+ }
907
+ end
908
+ end
909
+
880
910
  context 'result objects' do
881
911
  describe '#excerpts' do
882
912
  before :each do
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thinking-sphinx
3
3
  version: !ruby/object:Gem::Version
4
- hash: 11
4
+ hash: 9
5
5
  prerelease: false
6
6
  segments:
7
7
  - 2
8
8
  - 0
9
- - 2
10
- version: 2.0.2
9
+ - 3
10
+ version: 2.0.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Pat Allan
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-01-13 00:00:00 +11:00
18
+ date: 2011-04-03 00:00:00 +11:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -296,6 +296,7 @@ files:
296
296
  - lib/thinking_sphinx/active_record/attribute_updates.rb
297
297
  - lib/thinking_sphinx/active_record/delta.rb
298
298
  - lib/thinking_sphinx/active_record/has_many_association.rb
299
+ - lib/thinking_sphinx/active_record/has_many_association_with_scopes.rb
299
300
  - lib/thinking_sphinx/active_record/log_subscriber.rb
300
301
  - lib/thinking_sphinx/active_record/scopes.rb
301
302
  - lib/thinking_sphinx/adapters/abstract_adapter.rb