pg_search 0.5.5 → 0.5.6

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc CHANGED
@@ -1,5 +1,12 @@
1
1
  = PgSearch
2
2
 
3
+ == 0.5.6
4
+
5
+ * PgSearch#multisearchable accepts :if and :unless for conditional inclusion
6
+ in search documents table. (Francois Harbec)
7
+
8
+ * Stop using array_to_string() in SQL since it is not indexable.
9
+
3
10
  == 0.5.5
4
11
 
5
12
  * Fix bug with single table inheritance.
data/Gemfile CHANGED
@@ -4,6 +4,7 @@ gemspec
4
4
 
5
5
  gem "rake"
6
6
  gem "rdoc"
7
+ gem "pry"
7
8
 
8
9
  platforms :ruby do
9
10
  gem 'pg'
data/README.rdoc CHANGED
@@ -73,6 +73,20 @@ To add a model to the global search index for your application, call multisearch
73
73
 
74
74
  Whenever a record is created, updated, or destroyed, an Active Record callback will fire, leading to the creation of a corresponding PgSearch::Document record in the pg_search_documents table. The :against option can be one or several methods which will be called on the record to generate its search text.
75
75
 
76
+ You can also pass a Proc or method name to call to determine whether or not a particular record should be included.
77
+
78
+ class Convertible < ActiveRecord::Base
79
+ include PgSearch
80
+ multisearchable :against => [:make, :model],
81
+ :if => :available_in_red?
82
+ end
83
+
84
+ class Jalopy < ActiveRecord::Base
85
+ include PgSearch
86
+ multisearchable :against => [:make, :model],
87
+ :if => lambda { |record| record.model_year > 1970 }
88
+ end
89
+
76
90
  ==== Multi-search associations
77
91
 
78
92
  Two associations are built automatically. On the original record, there is a has_one :pg_search_document association pointing to the PgSearch::Document record, and on the PgSearch::Document record there is a belongs_to :searchable polymorphic association pointing back to the original record.
@@ -14,12 +14,7 @@ module PgSearch
14
14
  attr_reader :query, :options, :columns, :model, :normalizer
15
15
 
16
16
  def document
17
- if columns.length == 1
18
- columns.first.to_sql
19
- else
20
- expressions = columns.map { |column| column.to_sql }.join(", ")
21
- "array_to_string(ARRAY[#{expressions}], ' ')"
22
- end
17
+ columns.map { |column| column.to_sql }.join(" || ' ' || ")
23
18
  end
24
19
 
25
20
  def normalize(expression)
@@ -1,17 +1,20 @@
1
1
  module PgSearch
2
2
  module Multisearch
3
3
  class Rebuilder
4
- def initialize(model)
4
+ def initialize(model, time_source = Time.method(:now))
5
5
  unless model.respond_to?(:pg_search_multisearchable_options)
6
6
  raise ModelNotMultisearchable.new(model)
7
7
  end
8
8
 
9
9
  @model = model
10
+ @time_source = time_source
10
11
  end
11
12
 
12
13
  def rebuild
13
14
  if model.respond_to?(:rebuild_pg_search_documents)
14
15
  model.rebuild_pg_search_documents
16
+ elsif model.pg_search_multisearchable_options.key?(:if) || model.pg_search_multisearchable_options.key?(:unless)
17
+ model.find_each { |record| record.update_pg_search_document }
15
18
  else
16
19
  model.connection.execute(rebuild_sql)
17
20
  end
@@ -70,7 +73,7 @@ SQL
70
73
  end
71
74
 
72
75
  def current_time
73
- connection.quote(connection.quoted_date(Time.now))
76
+ connection.quote(connection.quoted_date(@time_source.call))
74
77
  end
75
78
  end
76
79
  end
@@ -16,10 +16,17 @@ module PgSearch
16
16
  end
17
17
 
18
18
  def update_pg_search_document
19
- if self.pg_search_document
20
- self.pg_search_document.save
19
+ if_conditions = Array(pg_search_multisearchable_options[:if])
20
+ unless_conditions = Array(pg_search_multisearchable_options[:unless])
21
+
22
+ should_have_document =
23
+ if_conditions.all? { |condition| condition.to_proc.call(self) } &&
24
+ unless_conditions.all? { |condition| !condition.to_proc.call(self) }
25
+
26
+ if should_have_document
27
+ pg_search_document ? pg_search_document.save : create_pg_search_document
21
28
  else
22
- create_pg_search_document
29
+ pg_search_document.destroy if pg_search_document
23
30
  end
24
31
  end
25
32
  end
@@ -1,3 +1,3 @@
1
1
  module PgSearch
2
- VERSION = "0.5.5"
2
+ VERSION = "0.5.6"
3
3
  end
@@ -0,0 +1,188 @@
1
+ require "spec_helper"
2
+
3
+ describe PgSearch::Multisearch::Rebuilder do
4
+ with_table "pg_search_documents", {}, &DOCUMENTS_SCHEMA
5
+
6
+ describe "#rebuild" do
7
+ context "when the model defines .rebuild_pg_search_documents" do
8
+ context "and multisearchable is not conditional" do
9
+ with_model :Model do
10
+ model do
11
+ include PgSearch
12
+ multisearchable
13
+
14
+ def rebuild_pg_search_documents
15
+ end
16
+ end
17
+ end
18
+
19
+ it "should call .rebuild_pg_search_documents" do
20
+ rebuilder = PgSearch::Multisearch::Rebuilder.new(Model)
21
+ Model.should_receive(:rebuild_pg_search_documents)
22
+ rebuilder.rebuild
23
+ end
24
+ end
25
+
26
+ context "when multisearch is conditional" do
27
+ [:if, :unless].each do |conditional_key|
28
+ context "via :#{conditional_key}" do
29
+ with_model :Model do
30
+ table do |t|
31
+ t.boolean :active
32
+ end
33
+
34
+ model do
35
+ include PgSearch
36
+ multisearchable conditional_key => :active?
37
+
38
+ def rebuild_pg_search_documents
39
+ end
40
+ end
41
+ end
42
+
43
+ it "should call .rebuild_pg_search_documents" do
44
+ rebuilder = PgSearch::Multisearch::Rebuilder.new(Model)
45
+ Model.should_receive(:rebuild_pg_search_documents)
46
+ rebuilder.rebuild
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ context "when the model does not define .rebuild_pg_search_documents" do
54
+ context "when multisearchable is not conditional" do
55
+ with_model :Model do
56
+ table do |t|
57
+ t.string :name
58
+ end
59
+
60
+ model do
61
+ include PgSearch
62
+ multisearchable :against => :name
63
+ end
64
+ end
65
+
66
+ it "should not call :rebuild_pg_search_documents" do
67
+ rebuilder = PgSearch::Multisearch::Rebuilder.new(Model)
68
+
69
+ # stub respond_to? to return false since should_not_receive defines the method
70
+ original_respond_to = Model.method(:respond_to?)
71
+ Model.stub(:respond_to?) do |method_name, *args|
72
+ if method_name == :rebuild_pg_search_documents
73
+ false
74
+ else
75
+ original_respond_to.call(method_name, *args)
76
+ end
77
+ end
78
+
79
+ Model.should_not_receive(:rebuild_pg_search_documents)
80
+ rebuilder.rebuild
81
+ end
82
+
83
+ it "should execute the default SQL" do
84
+ time = DateTime.parse("2001-01-01")
85
+ rebuilder = PgSearch::Multisearch::Rebuilder.new(Model, lambda { time } )
86
+
87
+ expected_sql = <<-SQL
88
+ INSERT INTO "pg_search_documents" (searchable_type, searchable_id, content, created_at, updated_at)
89
+ SELECT 'Model' AS searchable_type,
90
+ #{Model.quoted_table_name}.id AS searchable_id,
91
+ (
92
+ coalesce(#{Model.quoted_table_name}.name::text, '')
93
+ ) AS content,
94
+ '2001-01-01 00:00:00' AS created_at,
95
+ '2001-01-01 00:00:00' AS updated_at
96
+ FROM #{Model.quoted_table_name}
97
+ SQL
98
+
99
+ executed_sql = []
100
+
101
+ notifier = ActiveSupport::Notifications.subscribe("sql.active_record") do |name, start, finish, id, payload|
102
+ executed_sql << payload[:sql]
103
+ end
104
+
105
+ rebuilder.rebuild
106
+ ActiveSupport::Notifications.unsubscribe(notifier)
107
+
108
+ executed_sql.length.should == 1
109
+ executed_sql.first.should == expected_sql
110
+ end
111
+ end
112
+
113
+ context "when multisearchable is conditional" do
114
+ context "via :if" do
115
+ with_model :Model do
116
+ table do |t|
117
+ t.boolean :active
118
+ end
119
+
120
+ model do
121
+ include PgSearch
122
+ multisearchable :if => :active?
123
+ end
124
+ end
125
+
126
+ it "calls update_pg_search_document on each record" do
127
+ record1 = Model.create!(:active => true)
128
+ record2 = Model.create!(:active => false)
129
+
130
+ rebuilder = PgSearch::Multisearch::Rebuilder.new(Model)
131
+
132
+ # stub respond_to? to return false since should_not_receive defines the method
133
+ original_respond_to = Model.method(:respond_to?)
134
+ Model.stub(:respond_to?) do |method_name, *args|
135
+ if method_name == :rebuild_pg_search_documents
136
+ false
137
+ else
138
+ original_respond_to.call(method_name, *args)
139
+ end
140
+ end
141
+ Model.should_not_receive(:rebuild_pg_search_documents)
142
+
143
+ rebuilder.rebuild
144
+
145
+ record1.pg_search_document.should be_present
146
+ record2.pg_search_document.should_not be_present
147
+ end
148
+ end
149
+
150
+ context "via :unless" do
151
+ with_model :Model do
152
+ table do |t|
153
+ t.boolean :inactive
154
+ end
155
+
156
+ model do
157
+ include PgSearch
158
+ multisearchable :unless => :inactive?
159
+ end
160
+ end
161
+
162
+ it "calls update_pg_search_document on each record" do
163
+ record1 = Model.create!(:inactive => true)
164
+ record2 = Model.create!(:inactive => false)
165
+
166
+ rebuilder = PgSearch::Multisearch::Rebuilder.new(Model)
167
+
168
+ # stub respond_to? to return false since should_not_receive defines the method
169
+ original_respond_to = Model.method(:respond_to?)
170
+ Model.stub(:respond_to?) do |method_name, *args|
171
+ if method_name == :rebuild_pg_search_documents
172
+ false
173
+ else
174
+ original_respond_to.call(method_name, *args)
175
+ end
176
+ end
177
+ Model.should_not_receive(:rebuild_pg_search_documents)
178
+
179
+ rebuilder.rebuild
180
+
181
+ record1.pg_search_document.should_not be_present
182
+ record2.pg_search_document.should be_present
183
+ end
184
+ end
185
+ end
186
+ end
187
+ end
188
+ end
@@ -3,14 +3,8 @@ require "spec_helper"
3
3
  describe PgSearch::Multisearchable do
4
4
  with_table "pg_search_documents", {}, &DOCUMENTS_SCHEMA
5
5
 
6
- before { PgSearch.stub(:multisearch_enabled?) { true } }
7
-
8
6
  describe "a model that is multisearchable" do
9
- subject { ModelThatIsMultisearchable }
10
-
11
7
  with_model :ModelThatIsMultisearchable do
12
- table do |t|
13
- end
14
8
  model do
15
9
  include PgSearch
16
10
  multisearchable
@@ -22,27 +16,26 @@ describe PgSearch::Multisearchable do
22
16
  let(:record) { ModelThatIsMultisearchable.new }
23
17
 
24
18
  describe "saving the record" do
25
- subject do
26
- lambda { record.save! }
27
- end
28
-
29
- context "with multisearch enabled" do
30
- before { PgSearch.stub(:multisearch_enabled?) { true } }
31
- it { should change(PgSearch::Document, :count).by(1) }
19
+ it "should create a PgSearch::Document record" do
20
+ expect { record.save! }.to change(PgSearch::Document, :count).by(1)
32
21
  end
33
22
 
34
23
  context "with multisearch disabled" do
35
- before { PgSearch.stub(:multisearch_enabled?) { false } }
36
- it { should_not change(PgSearch::Document, :count) }
24
+ before { PgSearch.stub(:multisearch_enabled? => false) }
25
+
26
+ it "should not create a PgSearch::Document record" do
27
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
28
+ end
37
29
  end
38
30
  end
39
31
 
40
32
  describe "the document" do
41
- subject { document }
42
- before { record.save! }
43
- let(:document) { PgSearch::Document.last }
44
-
45
- its(:searchable) { should == record }
33
+ it "should be associated to the record" do
34
+ record.save!
35
+ newest_pg_search_document = PgSearch::Document.last
36
+ record.pg_search_document.should == newest_pg_search_document
37
+ newest_pg_search_document.searchable.should == record
38
+ end
46
39
  end
47
40
  end
48
41
 
@@ -50,23 +43,25 @@ describe PgSearch::Multisearchable do
50
43
  let!(:record) { ModelThatIsMultisearchable.create! }
51
44
 
52
45
  context "when the document is present" do
46
+ before { record.pg_search_document.should be_present }
47
+
53
48
  describe "saving the record" do
54
- subject do
55
- lambda { record.save! }
49
+ it "calls save on the pg_search_document" do
50
+ record.pg_search_document.should_receive(:save)
51
+ record.save!
56
52
  end
57
53
 
58
- context "with multisearch enabled" do
59
- before { PgSearch.stub(:multisearch_enabled?) { true } }
60
-
61
- before { record.pg_search_document.should_receive(:save) }
62
- it { should_not change(PgSearch::Document, :count) }
54
+ it "should not create a PgSearch::Document record" do
55
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
63
56
  end
64
57
 
65
58
  context "with multisearch disabled" do
66
- before { PgSearch.stub(:multisearch_enabled?) { false } }
59
+ before { PgSearch.stub(:multisearch_enabled? => false) }
67
60
 
68
- before { record.pg_search_document.should_not_receive(:save) }
69
- it { should_not change(PgSearch::Document, :count) }
61
+ it "should not create a PgSearch::Document record" do
62
+ record.pg_search_document.should_not_receive(:save)
63
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
64
+ end
70
65
  end
71
66
  end
72
67
  end
@@ -75,18 +70,16 @@ describe PgSearch::Multisearchable do
75
70
  before { record.pg_search_document = nil }
76
71
 
77
72
  describe "saving the record" do
78
- subject do
79
- lambda { record.save! }
80
- end
81
-
82
- context "with multisearch enabled" do
83
- before { PgSearch.stub(:multisearch_enabled?) { true } }
84
- it { should change(PgSearch::Document, :count).by(1) }
73
+ it "should create a PgSearch::Document record" do
74
+ expect { record.save! }.to change(PgSearch::Document, :count).by(1)
85
75
  end
86
76
 
87
77
  context "with multisearch disabled" do
88
- before { PgSearch.stub(:multisearch_enabled?) { false } }
89
- it { should_not change(PgSearch::Document, :count) }
78
+ before { PgSearch.stub(:multisearch_enabled? => false) }
79
+
80
+ it "should not create a PgSearch::Document record" do
81
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
82
+ end
90
83
  end
91
84
  end
92
85
  end
@@ -96,14 +89,531 @@ describe PgSearch::Multisearchable do
96
89
  it "should remove its document" do
97
90
  record = ModelThatIsMultisearchable.create!
98
91
  document = record.pg_search_document
92
+ expect { record.destroy }.to change(PgSearch::Document, :count).by(-1)
93
+ expect { PgSearch::Document.find(document.id) }.to raise_error(ActiveRecord::RecordNotFound)
94
+ end
95
+ end
96
+ end
97
+ end
98
+
99
+ describe "a model which is conditionally multisearchable using a Proc" do
100
+ context "via :if" do
101
+ with_model :ModelThatIsMultisearchable do
102
+ table do |t|
103
+ t.boolean :multisearchable
104
+ end
105
+
106
+ model do
107
+ include PgSearch
108
+ multisearchable :if => lambda { |record| record.multisearchable? }
109
+ end
110
+ end
111
+
112
+ describe "callbacks" do
113
+ describe "after_create" do
114
+ describe "saving the record" do
115
+ context "when the condition is true" do
116
+ let(:record) { ModelThatIsMultisearchable.new(:multisearchable => true) }
117
+
118
+ it "should create a PgSearch::Document record" do
119
+ expect { record.save! }.to change(PgSearch::Document, :count).by(1)
120
+ end
121
+
122
+ context "with multisearch disabled" do
123
+ before { PgSearch.stub(:multisearch_enabled? => false) }
124
+
125
+ it "should not create a PgSearch::Document record" do
126
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
127
+ end
128
+ end
129
+ end
130
+
131
+ context "when the condition is false" do
132
+ let(:record) { ModelThatIsMultisearchable.new(:multisearchable => false) }
133
+
134
+ it "should not create a PgSearch::Document record" do
135
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
136
+ end
137
+ end
138
+ end
139
+ end
140
+
141
+ describe "after_update" do
142
+ let(:record) { ModelThatIsMultisearchable.create!(:multisearchable => true) }
143
+
144
+ context "when the document is present" do
145
+ before { record.pg_search_document.should be_present }
146
+
147
+ describe "saving the record" do
148
+ context "when the condition is true" do
149
+ it "calls save on the pg_search_document" do
150
+ record.pg_search_document.should_receive(:save)
151
+ record.save!
152
+ end
153
+
154
+ it "should not create a PgSearch::Document record" do
155
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
156
+ end
157
+ end
158
+
159
+ context "when the condition is false" do
160
+ before { record.multisearchable = false }
161
+
162
+ it "calls destroy on the pg_search_document" do
163
+ record.pg_search_document.should_receive(:destroy)
164
+ record.save!
165
+ end
166
+
167
+ it "should remove its document" do
168
+ document = record.pg_search_document
169
+ expect { record.save! }.to change(PgSearch::Document, :count).by(-1)
170
+ expect { PgSearch::Document.find(document.id) }.to raise_error(ActiveRecord::RecordNotFound)
171
+ end
172
+ end
173
+
174
+ context "with multisearch disabled" do
175
+ before do
176
+ PgSearch.stub(:multisearch_enabled? => false)
177
+ record.pg_search_document.should_not_receive(:save)
178
+ end
179
+
180
+ it "should not create a PgSearch::Document record" do
181
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
182
+ end
183
+ end
184
+ end
185
+ end
186
+
187
+ context "when the document is missing" do
188
+ before { record.pg_search_document = nil }
99
189
 
100
- expect {
101
- record.destroy
102
- }.to change(PgSearch::Document, :count).by(-1)
190
+ describe "saving the record" do
191
+ context "when the condition is true" do
192
+ it "should create a PgSearch::Document record" do
193
+ expect { record.save! }.to change(PgSearch::Document, :count).by(1)
194
+ end
103
195
 
104
- expect {
105
- PgSearch::Document.find(document.id)
106
- }.to raise_error(ActiveRecord::RecordNotFound)
196
+ context "with multisearch disabled" do
197
+ before { PgSearch.stub(:multisearch_enabled? => false) }
198
+
199
+ it "should not create a PgSearch::Document record" do
200
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
201
+ end
202
+ end
203
+ end
204
+
205
+ context "when the condition is false" do
206
+ before { record.multisearchable = false }
207
+
208
+ it "should not create a PgSearch::Document record" do
209
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
210
+ end
211
+ end
212
+ end
213
+ end
214
+ end
215
+
216
+ describe "after_destroy" do
217
+ let(:record) { ModelThatIsMultisearchable.create!(:multisearchable => true) }
218
+
219
+ it "should remove its document" do
220
+ document = record.pg_search_document
221
+ expect { record.destroy }.to change(PgSearch::Document, :count).by(-1)
222
+ expect { PgSearch::Document.find(document.id) }.to raise_error(ActiveRecord::RecordNotFound)
223
+ end
224
+ end
225
+ end
226
+ end
227
+
228
+ context "using :unless" do
229
+ with_model :ModelThatIsMultisearchable do
230
+ table do |t|
231
+ t.boolean :not_multisearchable
232
+ end
233
+
234
+ model do
235
+ include PgSearch
236
+ multisearchable :unless => lambda { |record| record.not_multisearchable? }
237
+ end
238
+ end
239
+
240
+ describe "callbacks" do
241
+ describe "after_create" do
242
+ describe "saving the record" do
243
+ context "when the condition is false" do
244
+ let(:record) { ModelThatIsMultisearchable.new(:not_multisearchable => false) }
245
+
246
+ it "should create a PgSearch::Document record" do
247
+ expect { record.save! }.to change(PgSearch::Document, :count).by(1)
248
+ end
249
+
250
+ context "with multisearch disabled" do
251
+ before { PgSearch.stub(:multisearch_enabled? => false) }
252
+
253
+ it "should not create a PgSearch::Document record" do
254
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
255
+ end
256
+ end
257
+ end
258
+
259
+ context "when the condition is true" do
260
+ let(:record) { ModelThatIsMultisearchable.new(:not_multisearchable => true) }
261
+
262
+ it "should not create a PgSearch::Document record" do
263
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
264
+ end
265
+ end
266
+ end
267
+ end
268
+
269
+ describe "after_update" do
270
+ let!(:record) { ModelThatIsMultisearchable.create!(:not_multisearchable => false) }
271
+
272
+ context "when the document is present" do
273
+ before { record.pg_search_document.should be_present }
274
+
275
+ describe "saving the record" do
276
+ context "when the condition is false" do
277
+ it "calls save on the pg_search_document" do
278
+ record.pg_search_document.should_receive(:save)
279
+ record.save!
280
+ end
281
+
282
+ it "should not create a PgSearch::Document record" do
283
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
284
+ end
285
+
286
+ context "with multisearch disabled" do
287
+ before do
288
+ PgSearch.stub(:multisearch_enabled? => false)
289
+ record.pg_search_document.should_not_receive(:save)
290
+ end
291
+
292
+ it "should not create a PgSearch::Document record" do
293
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
294
+ end
295
+ end
296
+ end
297
+
298
+ context "when the condition is true" do
299
+ before { record.not_multisearchable = true }
300
+
301
+ it "calls destroy on the pg_search_document" do
302
+ record.pg_search_document.should_receive(:destroy)
303
+ record.save!
304
+ end
305
+
306
+ it "should remove its document" do
307
+ document = record.pg_search_document
308
+ expect { record.save! }.to change(PgSearch::Document, :count).by(-1)
309
+ expect { PgSearch::Document.find(document.id) }.to raise_error(ActiveRecord::RecordNotFound)
310
+ end
311
+ end
312
+
313
+ end
314
+ end
315
+
316
+ context "when the document is missing" do
317
+ before { record.pg_search_document = nil }
318
+
319
+ describe "saving the record" do
320
+ context "when the condition is false" do
321
+ it "should create a PgSearch::Document record" do
322
+ expect { record.save! }.to change(PgSearch::Document, :count).by(1)
323
+ end
324
+ end
325
+
326
+ context "when the condition is true" do
327
+ before { record.not_multisearchable = true }
328
+
329
+ it "should not create a PgSearch::Document record" do
330
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
331
+ end
332
+ end
333
+
334
+ context "with multisearch disabled" do
335
+ before { PgSearch.stub(:multisearch_enabled? => false) }
336
+ it "should not create a PgSearch::Document record" do
337
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
338
+ end
339
+ end
340
+ end
341
+ end
342
+ end
343
+
344
+ describe "after_destroy" do
345
+ it "should remove its document" do
346
+ record = ModelThatIsMultisearchable.create!
347
+ document = record.pg_search_document
348
+ expect { record.destroy }.to change(PgSearch::Document, :count).by(-1)
349
+ expect { PgSearch::Document.find(document.id) }.to raise_error(ActiveRecord::RecordNotFound)
350
+ end
351
+ end
352
+ end
353
+ end
354
+ end
355
+
356
+ describe "a model which is conditionally multisearchable using a Symbol" do
357
+ context "via :if" do
358
+ with_model :ModelThatIsMultisearchable do
359
+ table do |t|
360
+ t.boolean :multisearchable
361
+ end
362
+
363
+ model do
364
+ include PgSearch
365
+ multisearchable :if => :multisearchable?
366
+ end
367
+ end
368
+
369
+ describe "callbacks" do
370
+ describe "after_create" do
371
+ describe "saving the record" do
372
+ context "when the condition is true" do
373
+ let(:record) { ModelThatIsMultisearchable.new(:multisearchable => true) }
374
+
375
+ it "should create a PgSearch::Document record" do
376
+ expect { record.save! }.to change(PgSearch::Document, :count).by(1)
377
+ end
378
+
379
+ context "with multisearch disabled" do
380
+ before { PgSearch.stub(:multisearch_enabled? => false) }
381
+
382
+ it "should not create a PgSearch::Document record" do
383
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
384
+ end
385
+ end
386
+ end
387
+
388
+ context "when the condition is false" do
389
+ let(:record) { ModelThatIsMultisearchable.new(:multisearchable => false) }
390
+
391
+ it "should not create a PgSearch::Document record" do
392
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
393
+ end
394
+ end
395
+ end
396
+ end
397
+
398
+ describe "after_update" do
399
+ let!(:record) { ModelThatIsMultisearchable.create!(:multisearchable => true) }
400
+
401
+ context "when the document is present" do
402
+ before { record.pg_search_document.should be_present }
403
+
404
+ describe "saving the record" do
405
+ context "when the condition is true" do
406
+ it "calls save on the pg_search_document" do
407
+ record.pg_search_document.should_receive(:save)
408
+ record.save!
409
+ end
410
+
411
+ it "should not create a PgSearch::Document record" do
412
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
413
+ end
414
+
415
+ context "with multisearch disabled" do
416
+ before do
417
+ PgSearch.stub(:multisearch_enabled? => false)
418
+ record.pg_search_document.should_not_receive(:save)
419
+ end
420
+
421
+ it "should not create a PgSearch::Document record" do
422
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
423
+ end
424
+ end
425
+ end
426
+
427
+ context "when the condition is false" do
428
+ before { record.multisearchable = false }
429
+
430
+ it "calls destroy on the pg_search_document" do
431
+ record.pg_search_document.should_receive(:destroy)
432
+ record.save!
433
+ end
434
+
435
+ it "should remove its document" do
436
+ document = record.pg_search_document
437
+ expect { record.save! }.to change(PgSearch::Document, :count).by(-1)
438
+ expect { PgSearch::Document.find(document.id) }.to raise_error(ActiveRecord::RecordNotFound)
439
+ end
440
+ end
441
+ end
442
+ end
443
+
444
+ context "when the document is missing" do
445
+ before { record.pg_search_document = nil }
446
+
447
+ describe "saving the record" do
448
+ context "with multisearch enabled" do
449
+ before { PgSearch.stub(:multisearch_enabled? => true) }
450
+
451
+ context "when the condition is true" do
452
+ it "should create a PgSearch::Document record" do
453
+ expect { record.save! }.to change(PgSearch::Document, :count).by(1)
454
+ end
455
+ end
456
+
457
+ context "when the condition is false" do
458
+ before { record.multisearchable = false }
459
+
460
+ it "should not create a PgSearch::Document record" do
461
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
462
+ end
463
+ end
464
+ end
465
+
466
+ context "with multisearch disabled" do
467
+ before { PgSearch.stub(:multisearch_enabled? => false) }
468
+
469
+ it "should not create a PgSearch::Document record" do
470
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
471
+ end
472
+ end
473
+ end
474
+ end
475
+ end
476
+
477
+ describe "after_destroy" do
478
+ let(:record) { ModelThatIsMultisearchable.create!(:multisearchable => true) }
479
+
480
+ it "should remove its document" do
481
+ document = record.pg_search_document
482
+ expect { record.destroy }.to change(PgSearch::Document, :count).by(-1)
483
+ expect { PgSearch::Document.find(document.id) }.to raise_error(ActiveRecord::RecordNotFound)
484
+ end
485
+ end
486
+ end
487
+ end
488
+
489
+ context "using :unless" do
490
+ with_model :ModelThatIsMultisearchable do
491
+ table do |t|
492
+ t.boolean :not_multisearchable
493
+ end
494
+
495
+ model do
496
+ include PgSearch
497
+ multisearchable :unless => :not_multisearchable?
498
+ end
499
+ end
500
+
501
+ describe "callbacks" do
502
+ describe "after_create" do
503
+ describe "saving the record" do
504
+ context "when the condition is true" do
505
+ let(:record) { ModelThatIsMultisearchable.new(:not_multisearchable => true) }
506
+
507
+ it "should not create a PgSearch::Document record" do
508
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
509
+ end
510
+ end
511
+
512
+ context "when the condition is false" do
513
+ let(:record) { ModelThatIsMultisearchable.new(:not_multisearchable => false) }
514
+
515
+ it "should create a PgSearch::Document record" do
516
+ expect { record.save! }.to change(PgSearch::Document, :count).by(1)
517
+ end
518
+
519
+ context "with multisearch disabled" do
520
+ before { PgSearch.stub(:multisearch_enabled? => false) }
521
+
522
+ it "should not create a PgSearch::Document record" do
523
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
524
+ end
525
+ end
526
+ end
527
+ end
528
+ end
529
+
530
+ describe "after_update" do
531
+ let!(:record) { ModelThatIsMultisearchable.create!(:not_multisearchable => false) }
532
+
533
+ context "when the document is present" do
534
+ before { record.pg_search_document.should be_present }
535
+
536
+ describe "saving the record" do
537
+ context "when the condition is true" do
538
+ before { record.not_multisearchable = true }
539
+
540
+ it "calls destroy on the pg_search_document" do
541
+ record.pg_search_document.should_receive(:destroy)
542
+ record.save!
543
+ end
544
+
545
+ it "should remove its document" do
546
+ document = record.pg_search_document
547
+ expect { record.save! }.to change(PgSearch::Document, :count).by(-1)
548
+ expect { PgSearch::Document.find(document.id) }.to raise_error(ActiveRecord::RecordNotFound)
549
+ end
550
+ end
551
+
552
+ context "when the condition is false" do
553
+ it "calls save on the pg_search_document" do
554
+ record.pg_search_document.should_receive(:save)
555
+ record.save!
556
+ end
557
+
558
+ it "should not create a PgSearch::Document record" do
559
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
560
+ end
561
+
562
+ context "with multisearch disabled" do
563
+ before do
564
+ PgSearch.stub(:multisearch_enabled? => false)
565
+ record.pg_search_document.should_not_receive(:save)
566
+ end
567
+
568
+ it "should not create a PgSearch::Document record" do
569
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
570
+ end
571
+ end
572
+ end
573
+ end
574
+ end
575
+
576
+ context "when the document is missing" do
577
+ before { record.pg_search_document = nil }
578
+
579
+ describe "saving the record" do
580
+ context "with multisearch enabled" do
581
+ before { PgSearch.stub(:multisearch_enabled? => true) }
582
+
583
+ context "when the condition is true" do
584
+ before { record.not_multisearchable = true }
585
+
586
+ it "should not create a PgSearch::Document record" do
587
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
588
+ end
589
+ end
590
+
591
+ context "when the condition is false" do
592
+ it "should create a PgSearch::Document record" do
593
+ expect { record.save! }.to change(PgSearch::Document, :count).by(1)
594
+ end
595
+
596
+ context "with multisearch disabled" do
597
+ before { PgSearch.stub(:multisearch_enabled? => false) }
598
+
599
+ it "should not create a PgSearch::Document record" do
600
+ expect { record.save! }.not_to change(PgSearch::Document, :count)
601
+ end
602
+ end
603
+ end
604
+ end
605
+ end
606
+ end
607
+ end
608
+
609
+ describe "after_destroy" do
610
+ let(:record) { ModelThatIsMultisearchable.create!(:not_multisearchable => false) }
611
+
612
+ it "should remove its document" do
613
+ document = record.pg_search_document
614
+ expect { record.destroy }.to change(PgSearch::Document, :count).by(-1)
615
+ expect { PgSearch::Document.find(document.id) }.to raise_error(ActiveRecord::RecordNotFound)
616
+ end
107
617
  end
108
618
  end
109
619
  end
metadata CHANGED
@@ -1,56 +1,60 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: pg_search
3
- version: !ruby/object:Gem::Version
4
- version: 0.5.5
3
+ version: !ruby/object:Gem::Version
4
+ hash: 7
5
5
  prerelease:
6
+ segments:
7
+ - 0
8
+ - 5
9
+ - 6
10
+ version: 0.5.6
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Case Commons, LLC
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2012-09-16 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: activerecord
16
- requirement: !ruby/object:Gem::Requirement
17
+
18
+ date: 2012-09-29 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ version_requirements: &id001 !ruby/object:Gem::Requirement
17
22
  none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
21
- version: '3'
22
- type: :runtime
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ hash: 5
27
+ segments:
28
+ - 3
29
+ version: "3"
23
30
  prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
27
- - - ! '>='
28
- - !ruby/object:Gem::Version
29
- version: '3'
30
- - !ruby/object:Gem::Dependency
31
- name: activesupport
32
- requirement: !ruby/object:Gem::Requirement
33
- none: false
34
- requirements:
35
- - - ! '>='
36
- - !ruby/object:Gem::Version
37
- version: '3'
38
31
  type: :runtime
39
- prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
32
+ name: activerecord
33
+ requirement: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ version_requirements: &id002 !ruby/object:Gem::Requirement
41
36
  none: false
42
- requirements:
43
- - - ! '>='
44
- - !ruby/object:Gem::Version
45
- version: '3'
46
- description: PgSearch builds ActiveRecord named scopes that take advantage of PostgreSQL's
47
- full text search
48
- email:
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ hash: 5
41
+ segments:
42
+ - 3
43
+ version: "3"
44
+ prerelease: false
45
+ type: :runtime
46
+ name: activesupport
47
+ requirement: *id002
48
+ description: PgSearch builds ActiveRecord named scopes that take advantage of PostgreSQL's full text search
49
+ email:
49
50
  - casecommons-dev@googlegroups.com
50
51
  executables: []
52
+
51
53
  extensions: []
54
+
52
55
  extra_rdoc_files: []
53
- files:
56
+
57
+ files:
54
58
  - .autotest
55
59
  - .gitignore
56
60
  - .rspec
@@ -89,6 +93,7 @@ files:
89
93
  - pg_search.gemspec
90
94
  - spec/associations_spec.rb
91
95
  - spec/pg_search/document_spec.rb
96
+ - spec/pg_search/multisearch/rebuilder_spec.rb
92
97
  - spec/pg_search/multisearch_spec.rb
93
98
  - spec/pg_search/multisearchable_spec.rb
94
99
  - spec/pg_search/normalizer_spec.rb
@@ -102,38 +107,41 @@ files:
102
107
  - sql/unnest.sql
103
108
  homepage: https://github.com/Casecommons/pg_search
104
109
  licenses: []
110
+
105
111
  post_install_message:
106
112
  rdoc_options: []
107
- require_paths:
113
+
114
+ require_paths:
108
115
  - lib
109
- required_ruby_version: !ruby/object:Gem::Requirement
116
+ required_ruby_version: !ruby/object:Gem::Requirement
110
117
  none: false
111
- requirements:
112
- - - ! '>='
113
- - !ruby/object:Gem::Version
114
- version: '0'
115
- segments:
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ hash: 3
122
+ segments:
116
123
  - 0
117
- hash: -4514756727807360588
118
- required_rubygems_version: !ruby/object:Gem::Requirement
124
+ version: "0"
125
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
126
  none: false
120
- requirements:
121
- - - ! '>='
122
- - !ruby/object:Gem::Version
123
- version: '0'
124
- segments:
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ hash: 3
131
+ segments:
125
132
  - 0
126
- hash: -4514756727807360588
133
+ version: "0"
127
134
  requirements: []
135
+
128
136
  rubyforge_project:
129
137
  rubygems_version: 1.8.24
130
138
  signing_key:
131
139
  specification_version: 3
132
- summary: PgSearch builds ActiveRecord named scopes that take advantage of PostgreSQL's
133
- full text search
134
- test_files:
140
+ summary: PgSearch builds ActiveRecord named scopes that take advantage of PostgreSQL's full text search
141
+ test_files:
135
142
  - spec/associations_spec.rb
136
143
  - spec/pg_search/document_spec.rb
144
+ - spec/pg_search/multisearch/rebuilder_spec.rb
137
145
  - spec/pg_search/multisearch_spec.rb
138
146
  - spec/pg_search/multisearchable_spec.rb
139
147
  - spec/pg_search/normalizer_spec.rb