pg_search 0.5.5 → 0.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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