DrMark-thinking-sphinx 1.1.15 → 1.2.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/README.textile +22 -0
  2. data/VERSION.yml +4 -0
  3. data/lib/thinking_sphinx/active_record/scopes.rb +39 -0
  4. data/lib/thinking_sphinx/active_record.rb +27 -7
  5. data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +9 -3
  6. data/lib/thinking_sphinx/association.rb +4 -1
  7. data/lib/thinking_sphinx/attribute.rb +91 -30
  8. data/lib/thinking_sphinx/configuration.rb +51 -12
  9. data/lib/thinking_sphinx/deltas/datetime_delta.rb +2 -2
  10. data/lib/thinking_sphinx/deltas/default_delta.rb +1 -1
  11. data/lib/thinking_sphinx/deltas/delayed_delta/delta_job.rb +1 -1
  12. data/lib/thinking_sphinx/deltas/delayed_delta.rb +3 -0
  13. data/lib/thinking_sphinx/deploy/capistrano.rb +25 -8
  14. data/lib/thinking_sphinx/excerpter.rb +22 -0
  15. data/lib/thinking_sphinx/facet.rb +1 -1
  16. data/lib/thinking_sphinx/facet_search.rb +134 -0
  17. data/lib/thinking_sphinx/index.rb +2 -1
  18. data/lib/thinking_sphinx/rails_additions.rb +14 -0
  19. data/lib/thinking_sphinx/search.rb +599 -658
  20. data/lib/thinking_sphinx/search_methods.rb +421 -0
  21. data/lib/thinking_sphinx/source/internal_properties.rb +1 -1
  22. data/lib/thinking_sphinx/source/sql.rb +17 -13
  23. data/lib/thinking_sphinx/source.rb +6 -6
  24. data/lib/thinking_sphinx/tasks.rb +42 -8
  25. data/lib/thinking_sphinx.rb +82 -54
  26. data/rails/init.rb +14 -0
  27. data/spec/{unit → lib}/thinking_sphinx/active_record/delta_spec.rb +5 -5
  28. data/spec/{unit → lib}/thinking_sphinx/active_record/has_many_association_spec.rb +0 -0
  29. data/spec/lib/thinking_sphinx/active_record/scopes_spec.rb +96 -0
  30. data/spec/{unit → lib}/thinking_sphinx/active_record_spec.rb +51 -31
  31. data/spec/{unit → lib}/thinking_sphinx/association_spec.rb +4 -5
  32. data/spec/lib/thinking_sphinx/attribute_spec.rb +465 -0
  33. data/spec/{unit → lib}/thinking_sphinx/configuration_spec.rb +161 -29
  34. data/spec/{unit → lib}/thinking_sphinx/core/string_spec.rb +0 -0
  35. data/spec/lib/thinking_sphinx/excerpter_spec.rb +49 -0
  36. data/spec/lib/thinking_sphinx/facet_search_spec.rb +176 -0
  37. data/spec/{unit → lib}/thinking_sphinx/facet_spec.rb +24 -0
  38. data/spec/{unit → lib}/thinking_sphinx/field_spec.rb +8 -8
  39. data/spec/{unit → lib}/thinking_sphinx/index/builder_spec.rb +6 -2
  40. data/spec/{unit → lib}/thinking_sphinx/index/faux_column_spec.rb +0 -0
  41. data/spec/lib/thinking_sphinx/index_spec.rb +45 -0
  42. data/spec/{unit → lib}/thinking_sphinx/rails_additions_spec.rb +25 -5
  43. data/spec/lib/thinking_sphinx/search_methods_spec.rb +152 -0
  44. data/spec/lib/thinking_sphinx/search_spec.rb +960 -0
  45. data/spec/{unit → lib}/thinking_sphinx/source_spec.rb +63 -2
  46. data/spec/{unit → lib}/thinking_sphinx_spec.rb +32 -4
  47. data/tasks/distribution.rb +36 -35
  48. data/vendor/riddle/lib/riddle/client/message.rb +4 -3
  49. data/vendor/riddle/lib/riddle/client.rb +3 -0
  50. data/vendor/riddle/lib/riddle/configuration/section.rb +8 -2
  51. data/vendor/riddle/lib/riddle/controller.rb +17 -7
  52. data/vendor/riddle/lib/riddle.rb +1 -1
  53. metadata +79 -83
  54. data/lib/thinking_sphinx/active_record/search.rb +0 -57
  55. data/lib/thinking_sphinx/collection.rb +0 -148
  56. data/lib/thinking_sphinx/facet_collection.rb +0 -59
  57. data/lib/thinking_sphinx/search/facets.rb +0 -98
  58. data/spec/unit/thinking_sphinx/active_record/search_spec.rb +0 -107
  59. data/spec/unit/thinking_sphinx/attribute_spec.rb +0 -232
  60. data/spec/unit/thinking_sphinx/collection_spec.rb +0 -14
  61. data/spec/unit/thinking_sphinx/facet_collection_spec.rb +0 -64
  62. data/spec/unit/thinking_sphinx/index_spec.rb +0 -139
  63. data/spec/unit/thinking_sphinx/search_spec.rb +0 -130
@@ -5,22 +5,24 @@ end
5
5
  require 'active_record'
6
6
  require 'riddle'
7
7
  require 'after_commit'
8
+ require 'yaml'
8
9
 
9
10
  require 'thinking_sphinx/core/string'
10
11
  require 'thinking_sphinx/property'
11
12
  require 'thinking_sphinx/active_record'
12
13
  require 'thinking_sphinx/association'
13
14
  require 'thinking_sphinx/attribute'
14
- require 'thinking_sphinx/collection'
15
15
  require 'thinking_sphinx/configuration'
16
+ require 'thinking_sphinx/excerpter'
16
17
  require 'thinking_sphinx/facet'
17
18
  require 'thinking_sphinx/class_facet'
18
- require 'thinking_sphinx/facet_collection'
19
+ require 'thinking_sphinx/facet_search'
19
20
  require 'thinking_sphinx/field'
20
21
  require 'thinking_sphinx/index'
21
22
  require 'thinking_sphinx/source'
22
23
  require 'thinking_sphinx/rails_additions'
23
24
  require 'thinking_sphinx/search'
25
+ require 'thinking_sphinx/search_methods'
24
26
  require 'thinking_sphinx/deltas'
25
27
 
26
28
  require 'thinking_sphinx/adapters/abstract_adapter'
@@ -34,19 +36,11 @@ Merb::Plugins.add_rakefiles(
34
36
  ) if defined?(Merb)
35
37
 
36
38
  module ThinkingSphinx
37
- module Version #:nodoc:
38
- Major = 1
39
- Minor = 1
40
- Tiny = 15
41
-
42
- String = [Major, Minor, Tiny].join('.')
43
- end
44
-
45
39
  # A ConnectionError will get thrown when a connection to Sphinx can't be
46
40
  # made.
47
41
  class ConnectionError < StandardError
48
42
  end
49
-
43
+
50
44
  # A StaleIdsException is thrown by Collection.instances_from_matches if there
51
45
  # are records in Sphinx but not in the database, so the search can be retried.
52
46
  class StaleIdsException < StandardError
@@ -56,41 +50,50 @@ module ThinkingSphinx
56
50
  end
57
51
  end
58
52
 
53
+ # The current version of Thinking Sphinx.
54
+ #
55
+ # @return [String] The version number as a string
56
+ #
57
+ def self.version
58
+ hash = YAML.load_file File.join(File.dirname(__FILE__), '../VERSION.yml')
59
+ [hash[:major], hash[:minor], hash[:patch]].join('.')
60
+ end
61
+
59
62
  # The collection of indexed models. Keep in mind that Rails lazily loads
60
63
  # its classes, so this may not actually be populated with _all_ the models
61
64
  # that have Sphinx indexes.
62
65
  def self.indexed_models
63
66
  @@indexed_models ||= []
64
67
  end
65
-
68
+
66
69
  def self.unique_id_expression(offset = nil)
67
70
  "* #{ThinkingSphinx.indexed_models.size} + #{offset || 0}"
68
71
  end
69
-
72
+
70
73
  # Check if index definition is disabled.
71
- #
74
+ #
72
75
  def self.define_indexes?
73
76
  @@define_indexes = true unless defined?(@@define_indexes)
74
77
  @@define_indexes == true
75
78
  end
76
-
79
+
77
80
  # Enable/disable indexes - you may want to do this while migrating data.
78
- #
81
+ #
79
82
  # ThinkingSphinx.define_indexes = false
80
- #
83
+ #
81
84
  def self.define_indexes=(value)
82
85
  @@define_indexes = value
83
86
  end
84
-
87
+
85
88
  @@deltas_enabled = nil
86
89
 
87
90
  # Check if delta indexing is enabled.
88
- #
91
+ #
89
92
  def self.deltas_enabled?
90
93
  @@deltas_enabled = (ThinkingSphinx::Configuration.environment != 'test') if @@deltas_enabled.nil?
91
94
  @@deltas_enabled
92
95
  end
93
-
96
+
94
97
  # Enable/disable all delta indexing.
95
98
  #
96
99
  # ThinkingSphinx.deltas_enabled = false
@@ -98,38 +101,38 @@ module ThinkingSphinx
98
101
  def self.deltas_enabled=(value)
99
102
  @@deltas_enabled = value
100
103
  end
101
-
104
+
102
105
  @@updates_enabled = nil
103
-
106
+
104
107
  # Check if updates are enabled. True by default, unless within the test
105
108
  # environment.
106
- #
109
+ #
107
110
  def self.updates_enabled?
108
111
  @@updates_enabled = (ThinkingSphinx::Configuration.environment != 'test') if @@updates_enabled.nil?
109
112
  @@updates_enabled
110
113
  end
111
-
114
+
112
115
  # Enable/disable updates to Sphinx
113
- #
116
+ #
114
117
  # ThinkingSphinx.updates_enabled = false
115
118
  #
116
119
  def self.updates_enabled=(value)
117
120
  @@updates_enabled = value
118
121
  end
119
-
122
+
120
123
  @@suppress_delta_output = false
121
-
124
+
122
125
  def self.suppress_delta_output?
123
126
  @@suppress_delta_output
124
127
  end
125
-
128
+
126
129
  def self.suppress_delta_output=(value)
127
130
  @@suppress_delta_output = value
128
131
  end
129
-
132
+
130
133
  # Checks to see if MySQL will allow simplistic GROUP BY statements. If not,
131
134
  # or if not using MySQL, this will return false.
132
- #
135
+ #
133
136
  def self.use_group_by_shortcut?
134
137
  !!(
135
138
  mysql? && ::ActiveRecord::Base.connection.select_all(
@@ -137,46 +140,71 @@ module ThinkingSphinx
137
140
  ).all? { |key,value| value.nil? || value[/ONLY_FULL_GROUP_BY/].nil? }
138
141
  )
139
142
  end
140
-
143
+
144
+ @@remote_sphinx = false
145
+
146
+ # An indication of whether Sphinx is running on a remote machine instead of
147
+ # the same machine.
148
+ #
149
+ def self.remote_sphinx?
150
+ @@remote_sphinx
151
+ end
152
+
153
+ # Tells Thinking Sphinx that Sphinx is running on a different machine, and
154
+ # thus it can't reliably guess whether it is running or not (ie: the
155
+ # #sphinx_running? method), and so just assumes it is.
156
+ #
157
+ # Useful for multi-machine deployments. Set it in your production.rb file.
158
+ #
159
+ # ThinkingSphinx.remote_sphinx = true
160
+ #
161
+ def self.remote_sphinx=(value)
162
+ @@remote_sphinx = value
163
+ end
164
+
165
+ # Check if Sphinx is running. If remote_sphinx is set to true (indicating
166
+ # Sphinx is on a different machine), this will always return true, and you
167
+ # will have to handle any connection errors yourself.
168
+ #
141
169
  def self.sphinx_running?
170
+ remote_sphinx? || sphinx_running_by_pid?
171
+ end
172
+
173
+ # Check if Sphinx is actually running, provided the pid is on the same
174
+ # machine as this code.
175
+ #
176
+ def self.sphinx_running_by_pid?
142
177
  !!sphinx_pid && pid_active?(sphinx_pid)
143
178
  end
144
-
179
+
145
180
  def self.sphinx_pid
146
- pid_file = ThinkingSphinx::Configuration.instance.pid_file
147
- cat_command = 'cat'
148
- return nil unless File.exists?(pid_file)
149
-
150
- if microsoft?
151
- pid_file.gsub!('/', '\\')
152
- cat_command = 'type'
181
+ if File.exists?(ThinkingSphinx::Configuration.instance.pid_file)
182
+ File.read(ThinkingSphinx::Configuration.instance.pid_file)[/\d+/]
183
+ else
184
+ nil
153
185
  end
154
-
155
- `#{cat_command} #{pid_file}`[/\d+/]
156
186
  end
157
-
187
+
158
188
  def self.pid_active?(pid)
159
- return true if microsoft?
160
-
161
- begin
162
- # In JRuby this returns -1 if the process doesn't exist
163
- Process.getpgid(pid.to_i) != -1
164
- rescue Exception => e
165
- false
166
- end
189
+ !!Process.kill(0, pid.to_i)
190
+ rescue Exception => e
191
+ false
167
192
  end
168
-
193
+
169
194
  def self.microsoft?
170
195
  RUBY_PLATFORM =~ /mswin/
171
196
  end
172
-
197
+
173
198
  def self.jruby?
174
199
  defined?(JRUBY_VERSION)
175
200
  end
176
-
201
+
177
202
  def self.mysql?
178
- ::ActiveRecord::Base.connection.class.name.demodulize == "MysqlAdapter" || (
203
+ ::ActiveRecord::Base.connection.class.name.demodulize == "MysqlAdapter" ||
204
+ ::ActiveRecord::Base.connection.class.name.demodulize == "MysqlplusAdapter" || (
179
205
  jruby? && ::ActiveRecord::Base.connection.config[:adapter] == "jdbcmysql"
180
206
  )
181
207
  end
208
+
209
+ extend ThinkingSphinx::SearchMethods::ClassMethods
182
210
  end
data/rails/init.rb ADDED
@@ -0,0 +1,14 @@
1
+ require 'thinking_sphinx'
2
+ require 'action_controller/dispatcher'
3
+
4
+ ActionController::Dispatcher.to_prepare :thinking_sphinx do
5
+ # Force internationalisation to be loaded.
6
+ if Rails::VERSION::STRING.to_f > 2.2
7
+ I18n.backend.reload!
8
+ I18n.backend.available_locales
9
+ elsif Rails::VERSION::STRING.to_f > 2.1
10
+ I18n.backend.load_translations(*I18n.load_path)
11
+ end
12
+
13
+ ThinkingSphinx::Configuration.instance.load_models
14
+ end
@@ -80,7 +80,8 @@ describe "ThinkingSphinx::ActiveRecord::Delta" do
80
80
  :sphinx_document_id => 1
81
81
  )
82
82
 
83
- @client = Riddle::Client.stub_instance(:update => true)
83
+ @client = Riddle::Client.new
84
+ @client.stub!(:update => true)
84
85
  Riddle::Client.stub_method(:new => @client)
85
86
  end
86
87
 
@@ -120,17 +121,16 @@ describe "ThinkingSphinx::ActiveRecord::Delta" do
120
121
  end
121
122
 
122
123
  it "shouldn't update the deleted attribute if not in the index" do
123
- @person.send(:index_delta)
124
+ @client.should_not_receive(:update)
124
125
 
125
- @client.should_not have_received(:update)
126
+ @person.send(:index_delta)
126
127
  end
127
128
 
128
129
  it "should update the deleted attribute if in the core index" do
129
130
  @person.stub_method(:in_both_indexes? => true)
131
+ @client.should_receive(:update)
130
132
 
131
133
  @person.send(:index_delta)
132
-
133
- @client.should have_received(:update)
134
134
  end
135
135
  end
136
136
  end
@@ -0,0 +1,96 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe ThinkingSphinx::ActiveRecord::Scopes do
4
+ after :each do
5
+ Alpha.remove_sphinx_scopes
6
+ end
7
+
8
+ it "should be included into models with indexes" do
9
+ Alpha.included_modules.should include(ThinkingSphinx::ActiveRecord::Scopes)
10
+ end
11
+
12
+ it "should not be included into models without indexes" do
13
+ Gamma.included_modules.should_not include(
14
+ ThinkingSphinx::ActiveRecord::Scopes
15
+ )
16
+ end
17
+
18
+ describe '.sphinx_scope' do
19
+ before :each do
20
+ Alpha.sphinx_scope(:by_name) { |name| {:conditions => {:name => name}} }
21
+ end
22
+
23
+ it "should define a method on the model" do
24
+ Alpha.should respond_to(:by_name)
25
+ end
26
+ end
27
+
28
+ describe '.sphinx_scopes' do
29
+ before :each do
30
+ Alpha.sphinx_scope(:by_name) { |name| {:conditions => {:name => name}} }
31
+ end
32
+
33
+ it "should return an array of defined scope names as symbols" do
34
+ Alpha.sphinx_scopes.should == [:by_name]
35
+ end
36
+ end
37
+
38
+ describe '.remove_sphinx_scopes' do
39
+ before :each do
40
+ Alpha.sphinx_scope(:by_name) { |name| {:conditions => {:name => name}} }
41
+ Alpha.remove_sphinx_scopes
42
+ end
43
+
44
+ it "should remove sphinx scope methods" do
45
+ Alpha.should_not respond_to(:by_name)
46
+ end
47
+
48
+ it "should empty the list of sphinx scopes" do
49
+ Alpha.sphinx_scopes.should be_empty
50
+ end
51
+ end
52
+
53
+ describe '.example_scope' do
54
+ before :each do
55
+ Alpha.sphinx_scope(:by_name) { |name| {:conditions => {:name => name}} }
56
+ Alpha.sphinx_scope(:by_foo) { |foo| {:conditions => {:foo => foo}} }
57
+ Alpha.sphinx_scope(:with_betas) { {:classes => [Beta]} }
58
+ end
59
+
60
+ it "should return a ThinkingSphinx::Search object" do
61
+ Alpha.by_name('foo').should be_a(ThinkingSphinx::Search)
62
+ end
63
+
64
+ it "should set the classes option" do
65
+ Alpha.by_name('foo').options[:classes].should == [Alpha]
66
+ end
67
+
68
+ it "should be able to be called on a ThinkingSphinx::Search object" do
69
+ search = ThinkingSphinx::Search.new(:classes => [Alpha])
70
+ lambda {
71
+ search.by_name('foo')
72
+ }.should_not raise_error
73
+ end
74
+
75
+ it "should return the search object it gets called upon" do
76
+ search = ThinkingSphinx::Search.new(:classes => [Alpha])
77
+ search.by_name('foo').should == search
78
+ end
79
+
80
+ it "should apply the scope options to the underlying search object" do
81
+ search = ThinkingSphinx::Search.new(:classes => [Alpha])
82
+ search.by_name('foo').options[:conditions].should == {:name => 'foo'}
83
+ end
84
+
85
+ it "should combine hash option scopes such as :conditions" do
86
+ search = ThinkingSphinx::Search.new(:classes => [Alpha])
87
+ search.by_name('foo').by_foo('bar').options[:conditions].
88
+ should == {:name => 'foo', :foo => 'bar'}
89
+ end
90
+
91
+ it "should combine array option scopes such as :classes" do
92
+ search = ThinkingSphinx::Search.new(:classes => [Alpha])
93
+ search.with_betas.options[:classes].should == [Alpha, Beta]
94
+ end
95
+ end
96
+ end
@@ -3,7 +3,7 @@ require 'spec/spec_helper'
3
3
  describe "ThinkingSphinx::ActiveRecord" do
4
4
  describe "define_index method" do
5
5
  before :each do
6
- module TestModule
6
+ module ::TestModule
7
7
  class TestModel < ActiveRecord::Base; end
8
8
  end
9
9
 
@@ -185,7 +185,8 @@ describe "ThinkingSphinx::ActiveRecord" do
185
185
  :address => "an address",
186
186
  :port => 123
187
187
  )
188
- @client = Riddle::Client.stub_instance(:update => true)
188
+ @client = Riddle::Client.new
189
+ @client.stub!(:update => true)
189
190
  @person = Person.find(:first)
190
191
 
191
192
  Riddle::Client.stub_method(:new => @client)
@@ -202,87 +203,82 @@ describe "ThinkingSphinx::ActiveRecord" do
202
203
  end
203
204
 
204
205
  it "should update the core index's deleted flag if in core index" do
205
- @person.toggle_deleted
206
-
207
- @client.should have_received(:update).with(
206
+ @client.should_receive(:update).with(
208
207
  "person_core", ["sphinx_deleted"], {@person.sphinx_document_id => 1}
209
208
  )
209
+
210
+ @person.toggle_deleted
210
211
  end
211
212
 
212
213
  it "shouldn't update the core index's deleted flag if the record isn't in it" do
213
214
  @person.stub_method(:in_core_index? => false)
214
-
215
- @person.toggle_deleted
216
-
217
- @client.should_not have_received(:update).with(
215
+ @client.should_not_receive(:update).with(
218
216
  "person_core", ["sphinx_deleted"], {@person.sphinx_document_id => 1}
219
217
  )
218
+
219
+ @person.toggle_deleted
220
220
  end
221
221
 
222
222
  it "shouldn't attempt to update the deleted flag if sphinx isn't running" do
223
223
  ThinkingSphinx.stub_method(:sphinx_running? => false)
224
+ @client.should_not_receive(:update)
224
225
 
225
226
  @person.toggle_deleted
226
227
 
227
228
  @person.should_not have_received(:in_core_index?)
228
- @client.should_not have_received(:update)
229
229
  end
230
230
 
231
231
  it "should update the delta index's deleted flag if delta indexes are enabled and the instance's delta is true" do
232
232
  ThinkingSphinx.stub_method(:deltas_enabled? => true)
233
233
  Person.sphinx_indexes.each { |index| index.stub_method(:delta? => true) }
234
234
  @person.delta = true
235
-
236
- @person.toggle_deleted
237
-
238
- @client.should have_received(:update).with(
235
+ @client.should_receive(:update).with(
239
236
  "person_delta", ["sphinx_deleted"], {@person.sphinx_document_id => 1}
240
237
  )
238
+
239
+ @person.toggle_deleted
241
240
  end
242
241
 
243
242
  it "should not update the delta index's deleted flag if delta indexes are enabled and the instance's delta is false" do
244
243
  ThinkingSphinx.stub_method(:deltas_enabled? => true)
245
244
  Person.sphinx_indexes.each { |index| index.stub_method(:delta? => true) }
246
245
  @person.delta = false
247
-
248
- @person.toggle_deleted
249
-
250
- @client.should_not have_received(:update).with(
246
+ @client.should_not_receive(:update).with(
251
247
  "person_delta", ["sphinx_deleted"], {@person.sphinx_document_id => 1}
252
248
  )
249
+
250
+ @person.toggle_deleted
253
251
  end
254
252
 
255
253
  it "should not update the delta index's deleted flag if delta indexes are enabled and the instance's delta is equivalent to false" do
256
254
  ThinkingSphinx.stub_method(:deltas_enabled? => true)
257
255
  Person.sphinx_indexes.each { |index| index.stub_method(:delta? => true) }
258
256
  @person.delta = 0
259
-
260
- @person.toggle_deleted
261
-
262
- @client.should_not have_received(:update).with(
257
+ @client.should_not_receive(:update).with(
263
258
  "person_delta", ["sphinx_deleted"], {@person.sphinx_document_id => 1}
264
259
  )
260
+
261
+ @person.toggle_deleted
265
262
  end
266
263
 
267
264
  it "shouldn't update the delta index if delta indexes are disabled" do
268
265
  ThinkingSphinx.stub_method(:deltas_enabled? => true)
269
- @person.toggle_deleted
270
-
271
- @client.should_not have_received(:update).with(
266
+ @client.should_not_receive(:update).with(
272
267
  "person_delta", ["sphinx_deleted"], {@person.sphinx_document_id => 1}
273
268
  )
269
+
270
+ @person.toggle_deleted
274
271
  end
275
272
 
276
273
  it "should not update the delta index if delta indexing is disabled" do
277
274
  ThinkingSphinx.stub_method(:deltas_enabled? => false)
278
275
  Person.sphinx_indexes.each { |index| index.stub_method(:delta? => true) }
279
276
  @person.delta = true
280
-
281
- @person.toggle_deleted
282
-
283
- @client.should_not have_received(:update).with(
277
+ @client.should_not_receive(:update).with(
284
278
  "person_delta", ["sphinx_deleted"], {@person.sphinx_document_id => 1}
285
279
  )
280
+
281
+ @person.toggle_deleted
286
282
  end
287
283
 
288
284
  it "should not update either index if updates are disabled" do
@@ -292,10 +288,9 @@ describe "ThinkingSphinx::ActiveRecord" do
292
288
  )
293
289
  Person.sphinx_indexes.each { |index| index.stub_method(:delta? => true) }
294
290
  @person.delta = true
291
+ @client.should_not_receive(:update)
295
292
 
296
293
  @person.toggle_deleted
297
-
298
- @client.should_not have_received(:update)
299
294
  end
300
295
  end
301
296
 
@@ -331,4 +326,29 @@ describe "ThinkingSphinx::ActiveRecord" do
331
326
 
332
327
  (beta.id * model_count + offset).should == beta.sphinx_document_id
333
328
  end
329
+
330
+ describe '#primary_key_for_sphinx' do
331
+ before :each do
332
+ @person = Person.find(:first)
333
+ end
334
+
335
+ after :each do
336
+ Person.set_sphinx_primary_key nil
337
+ end
338
+
339
+ it "should return the id by default" do
340
+ @person.primary_key_for_sphinx.should == @person.id
341
+ end
342
+
343
+ it "should use the sphinx primary key to determine the value" do
344
+ Person.set_sphinx_primary_key :first_name
345
+ @person.primary_key_for_sphinx.should == @person.first_name
346
+ end
347
+
348
+ it "should not use accessor methods but the attributes hash" do
349
+ id = @person.id
350
+ @person.stub!(:id => 'unique_hash')
351
+ @person.primary_key_for_sphinx.should == id
352
+ end
353
+ end
334
354
  end
@@ -79,7 +79,8 @@ describe ThinkingSphinx::Association do
79
79
  before :each do
80
80
  @parent_join = ::ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation.stub_instance
81
81
  @join = ::ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation.stub_instance
82
- @parent = ThinkingSphinx::Association.stub_instance(:join_to => true, :join => nil)
82
+ @parent = ThinkingSphinx::Association.new(nil, nil)
83
+ @parent.stub!(:join_to => true, :join => nil)
83
84
  @base_join = Object.stub_instance(:joins => [:a, :b, :c])
84
85
 
85
86
  ::ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation.stub_method(:new => @join)
@@ -87,19 +88,17 @@ describe ThinkingSphinx::Association do
87
88
 
88
89
  it "should call the parent's join_to if parent has no join" do
89
90
  @assoc = ThinkingSphinx::Association.new(@parent, :ref)
91
+ @parent.should_receive(:join_to).with(@base_join)
90
92
 
91
93
  @assoc.join_to(@base_join)
92
-
93
- @parent.should have_received(:join_to).with(@base_join)
94
94
  end
95
95
 
96
96
  it "should not call the parent's join_to if it already has a join" do
97
97
  @assoc = ThinkingSphinx::Association.new(@parent, :ref)
98
98
  @parent.stub_method(:join => @parent_join)
99
+ @parent.should_not_receive(:join_to)
99
100
 
100
101
  @assoc.join_to(@base_join)
101
-
102
- @parent.should_not have_received(:join_to)
103
102
  end
104
103
 
105
104
  it "should define the join association with a JoinAssociation instance" do