pg_search 0.7.3 → 0.7.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 061b1d5b8c2b15a078a7e24519d6ce8431165a89
4
- data.tar.gz: 5f8d8ad2b97af42fe20a8bcbcfe3b506b865d29a
3
+ metadata.gz: 60b69d6e0600c725eba8d5f820eb05439982824a
4
+ data.tar.gz: d1f90c57f0d2db953516b2edf99127b0326be044
5
5
  SHA512:
6
- metadata.gz: 8395420354b745b6f31b860637ab36b0d3ade94bbc3fb5745c0d888d5feb7e2ff86a7790cc0f53360b540acfe8c1314d404cd3c48fe118a9bf2771be8210251e
7
- data.tar.gz: 3e3ee515686fada644a424e3372d6f1891faa3506a4c18993f899684de7450505e174d71abde33c16196e13a378e0673ba9d13727e58bbaa706cf6158aded71d
6
+ metadata.gz: 6157156f723baccc67229b771852de1adf1d21ffa5bc41e4a593908453c7af7125e1ae79ba46a0fa91de593e01c3b3117858e284c2e70b0cb9c7b4dd48184a27
7
+ data.tar.gz: 60a6c495d334f7af8dc4f98f9c20637de6058c218b1e35d98e1d298d923fa4bf6199ec456b8c6a5c1ab357d6c44e4b40348e16a99b92a03063dd8931fc4fa4d4
data/.travis.yml CHANGED
@@ -3,24 +3,24 @@ language: ruby
3
3
  rvm:
4
4
  - 1.9.3
5
5
  - 2.0.0
6
- - 2.1.0
6
+ - 2.1.1
7
7
  - jruby-19mode
8
8
 
9
9
  env:
10
10
  - ACTIVE_RECORD_BRANCH="master"
11
+ - ACTIVE_RECORD_BRANCH="4-1-stable"
11
12
  - ACTIVE_RECORD_BRANCH="4-0-stable"
12
- - ACTIVE_RECORD_VERSION="~> 4.1.0.beta1"
13
+ - ACTIVE_RECORD_VERSION="~> 4.1.0"
13
14
  - ACTIVE_RECORD_VERSION="~> 4.0.0"
14
15
  - ACTIVE_RECORD_VERSION="~> 3.2.0"
15
16
  - ACTIVE_RECORD_VERSION="~> 3.1.0"
16
17
 
17
18
  matrix:
18
19
  allow_failures:
19
- - rvm: 2.1.0
20
20
  - rvm: jruby-19mode
21
21
  - env: ACTIVE_RECORD_BRANCH="master"
22
+ - env: ACTIVE_RECORD_BRANCH="4-1-stable"
22
23
  - env: ACTIVE_RECORD_BRANCH="4-0-stable"
23
- - env: ACTIVE_RECORD_VERSION="~> 4.1.0.beta1"
24
24
 
25
25
  before_script:
26
26
  - "psql -c 'create database pg_search_test;' -U postgres >/dev/null"
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # pg_search changelog
2
2
 
3
+ ## 0.7.4
4
+
5
+ * Fix which STI class name is used for searchable_type for PgSearch::Document. (Ewan McDougall)
6
+ * Add support for non-standard primary keys. (Matt Beedle)
7
+
3
8
  ## 0.7.3
4
9
 
5
10
  * Allow simultaneously searching using `:associated_against` and `:tsvector_column` (Adam Becker)
data/README.md CHANGED
@@ -84,9 +84,11 @@ https://github.com/Casecommons/pg_search/tree/0.6-stable
84
84
 
85
85
  To add PgSearch to an Active Record model, simply include the PgSearch module.
86
86
 
87
- class Shape < ActiveRecord::Base
88
- include PgSearch
89
- end
87
+ ```ruby
88
+ class Shape < ActiveRecord::Base
89
+ include PgSearch
90
+ end
91
+ ```
90
92
 
91
93
  ### Multi-search vs. search scopes
92
94
 
@@ -118,15 +120,17 @@ pg_search_documents database table.
118
120
  To add a model to the global search index for your application, call
119
121
  multisearchable in its class definition.
120
122
 
121
- class EpicPoem < ActiveRecord::Base
122
- include PgSearch
123
- multisearchable :against => [:title, :author]
124
- end
123
+ ```ruby
124
+ class EpicPoem < ActiveRecord::Base
125
+ include PgSearch
126
+ multisearchable :against => [:title, :author]
127
+ end
125
128
 
126
- class Flower < ActiveRecord::Base
127
- include PgSearch
128
- multisearchable :against => :color
129
- end
129
+ class Flower < ActiveRecord::Base
130
+ include PgSearch
131
+ multisearchable :against => :color
132
+ end
133
+ ```
130
134
 
131
135
  If this model already has existing records, you will need to reindex this
132
136
  model to get existing records into the pg_search_documents table. See the
@@ -141,17 +145,19 @@ text.
141
145
  You can also pass a Proc or method name to call to determine whether or not a
142
146
  particular record should be included.
143
147
 
144
- class Convertible < ActiveRecord::Base
145
- include PgSearch
146
- multisearchable :against => [:make, :model],
147
- :if => :available_in_red?
148
- end
148
+ ```ruby
149
+ class Convertible < ActiveRecord::Base
150
+ include PgSearch
151
+ multisearchable :against => [:make, :model],
152
+ :if => :available_in_red?
153
+ end
149
154
 
150
- class Jalopy < ActiveRecord::Base
151
- include PgSearch
152
- multisearchable :against => [:make, :model],
153
- :if => lambda { |record| record.model_year > 1970 }
154
- end
155
+ class Jalopy < ActiveRecord::Base
156
+ include PgSearch
157
+ multisearchable :against => [:make, :model],
158
+ :if => lambda { |record| record.model_year > 1970 }
159
+ end
160
+ ```
155
161
 
156
162
  Note that the Proc or method name is called in an after_save hook. This means
157
163
  that you should be careful when using Time or other objects. In the following
@@ -159,33 +165,35 @@ example, if the record was last saved before the published_at timestamp, it
159
165
  won't get listed in global search at all until it is touched again after the
160
166
  timestamp.
161
167
 
162
- class AntipatternExample
163
- include PgSearch
164
- multisearchable :against => [:contents],
165
- :if => :published?
168
+ ```ruby
169
+ class AntipatternExample
170
+ include PgSearch
171
+ multisearchable :against => [:contents],
172
+ :if => :published?
166
173
 
167
- def published?
168
- published_at < Time.now
169
- end
170
- end
174
+ def published?
175
+ published_at < Time.now
176
+ end
177
+ end
171
178
 
172
- problematic_record = AntipatternExample.create!(
173
- :contents => "Using :if with a timestamp",
174
- :published_at => 10.minutes.from_now
175
- )
179
+ problematic_record = AntipatternExample.create!(
180
+ :contents => "Using :if with a timestamp",
181
+ :published_at => 10.minutes.from_now
182
+ )
176
183
 
177
- problematic_record.published? # => false
178
- PgSearch.multisearch("timestamp") # => No results
184
+ problematic_record.published? # => false
185
+ PgSearch.multisearch("timestamp") # => No results
179
186
 
180
- sleep 20.minutes
187
+ sleep 20.minutes
181
188
 
182
- problematic_record.published? # => true
183
- PgSearch.multisearch("timestamp") # => No results
189
+ problematic_record.published? # => true
190
+ PgSearch.multisearch("timestamp") # => No results
184
191
 
185
- problematic_record.save!
192
+ problematic_record.save!
186
193
 
187
- problematic_record.published? # => true
188
- PgSearch.multisearch("timestamp") # => Includes problematic_record
194
+ problematic_record.published? # => true
195
+ PgSearch.multisearch("timestamp") # => Includes problematic_record
196
+ ```
189
197
 
190
198
  #### Multi-search associations
191
199
 
@@ -194,19 +202,23 @@ has_one :pg_search_document association pointing to the PgSearch::Document
194
202
  record, and on the PgSearch::Document record there is a belongs_to :searchable
195
203
  polymorphic association pointing back to the original record.
196
204
 
197
- odyssey = EpicPoem.create!(:title => "Odyssey", :author => "Homer")
198
- search_document = odyssey.pg_search_document #=> PgSearch::Document instance
199
- search_document.searchable #=> #<EpicPoem id: 1, title: "Odyssey", author: "Homer">
205
+ ```ruby
206
+ odyssey = EpicPoem.create!(:title => "Odyssey", :author => "Homer")
207
+ search_document = odyssey.pg_search_document #=> PgSearch::Document instance
208
+ search_document.searchable #=> #<EpicPoem id: 1, title: "Odyssey", author: "Homer">
209
+ ```
200
210
 
201
211
  #### Searching in the global search index
202
212
 
203
213
  To fetch the PgSearch::Document entries for all of the records that match a
204
214
  given query, use PgSearch.multisearch.
205
215
 
206
- odyssey = EpicPoem.create!(:title => "Odyssey", :author => "Homer")
207
- rose = Flower.create!(:color => "Red")
208
- PgSearch.multisearch("Homer") #=> [#<PgSearch::Document searchable: odyssey>]
209
- PgSearch.multisearch("Red") #=> [#<PgSearch::Document searchable: rose>]
216
+ ```ruby
217
+ odyssey = EpicPoem.create!(:title => "Odyssey", :author => "Homer")
218
+ rose = Flower.create!(:color => "Red")
219
+ PgSearch.multisearch("Homer") #=> [#<PgSearch::Document searchable: odyssey>]
220
+ PgSearch.multisearch("Red") #=> [#<PgSearch::Document searchable: rose>]
221
+ ```
210
222
 
211
223
  #### Chaining method calls onto the results
212
224
 
@@ -215,12 +227,14 @@ so you can chain scope calls to the end. This works with gems like Kaminari
215
227
  that add scope methods. Just like with regular scopes, the database will only
216
228
  receive SQL requests when necessary.
217
229
 
218
- PgSearch.multisearch("Bertha").limit(10)
219
- PgSearch.multisearch("Juggler").where(:searchable_type => "Occupation")
220
- PgSearch.multisearch("Alamo").page(3).per_page(30)
221
- PgSearch.multisearch("Diagonal").find_each do |document|
222
- puts document.searchable.updated_at
223
- end
230
+ ```ruby
231
+ PgSearch.multisearch("Bertha").limit(10)
232
+ PgSearch.multisearch("Juggler").where(:searchable_type => "Occupation")
233
+ PgSearch.multisearch("Alamo").page(3).per_page(30)
234
+ PgSearch.multisearch("Diagonal").find_each do |document|
235
+ puts document.searchable.updated_at
236
+ end
237
+ ```
224
238
 
225
239
  #### Configuring multi-search
226
240
 
@@ -228,10 +242,12 @@ PgSearch.multisearch can be configured using the same options as
228
242
  `pg_search_scope` (explained in more detail below). Just set the
229
243
  PgSearch.multisearch_options in an initializer:
230
244
 
231
- PgSearch.multisearch_options = {
232
- :using => [:tsearch, :trigram],
233
- :ignoring => :accents
234
- }
245
+ ```ruby
246
+ PgSearch.multisearch_options = {
247
+ :using => [:tsearch, :trigram],
248
+ :ignoring => :accents
249
+ }
250
+ ```
235
251
 
236
252
  #### Rebuilding search documents for a given class
237
253
 
@@ -249,11 +265,15 @@ directly modify the database.
249
265
  To remove all of the documents for a given class, you can simply delete all of
250
266
  the PgSearch::Document records.
251
267
 
252
- PgSearch::Document.delete_all(:searchable_type => "Animal")
268
+ ```ruby
269
+ PgSearch::Document.delete_all(:searchable_type => "Animal")
270
+ ```
253
271
 
254
272
  To regenerate the documents for a given class, run:
255
273
 
256
- PgSearch::Multisearch.rebuild(Product)
274
+ ```ruby
275
+ PgSearch::Multisearch.rebuild(Product)
276
+ ```
257
277
 
258
278
  This is also available as a Rake task, for convenience.
259
279
 
@@ -271,41 +291,45 @@ Active Record attributes, an efficient single SQL statement is run to update
271
291
  the pg_search_documents table all at once. However, if you call any dynamic
272
292
  methods in :against, the following strategy will be used:
273
293
 
274
- PgSearch::Document.delete_all(:searchable_type => "Ingredient")
275
- Ingredient.find_each { |record| record.update_pg_search_document }
294
+ ```ruby
295
+ PgSearch::Document.delete_all(:searchable_type => "Ingredient")
296
+ Ingredient.find_each { |record| record.update_pg_search_document }
297
+ ```
276
298
 
277
299
  You can also provide a custom implementation for rebuilding the documents by
278
300
  adding a class method called `rebuild_pg_search_documents` to your model.
279
301
 
280
- class Movie < ActiveRecord::Base
281
- belongs_to :director
282
-
283
- def director_name
284
- director.name
285
- end
286
-
287
- multisearchable against: [:name, :director_name]
288
-
289
- # Naive approach
290
- def self.rebuild_pg_search_documents
291
- find_each { |record| record.update_pg_search_document }
292
- end
293
-
294
- # More sophisticated approach
295
- def self.rebuild_pg_search_documents
296
- connection.execute <<-SQL
297
- INSERT INTO pg_search_documents (searchable_type, searchable_id, content, created_at, updated_at)
298
- SELECT 'Movie' AS searchable_type,
299
- movies.id AS searchable_id,
300
- (movies.name || ' ' || directors.name) AS content,
301
- now() AS created_at,
302
- now() AS updated_at
303
- FROM movies
304
- LEFT JOIN directors
305
- ON directors.id = movies.director_id
306
- SQL
307
- end
308
- end
302
+ ```ruby
303
+ class Movie < ActiveRecord::Base
304
+ belongs_to :director
305
+
306
+ def director_name
307
+ director.name
308
+ end
309
+
310
+ multisearchable against: [:name, :director_name]
311
+
312
+ # Naive approach
313
+ def self.rebuild_pg_search_documents
314
+ find_each { |record| record.update_pg_search_document }
315
+ end
316
+
317
+ # More sophisticated approach
318
+ def self.rebuild_pg_search_documents
319
+ connection.execute <<-SQL
320
+ INSERT INTO pg_search_documents (searchable_type, searchable_id, content, created_at, updated_at)
321
+ SELECT 'Movie' AS searchable_type,
322
+ movies.id AS searchable_id,
323
+ (movies.name || ' ' || directors.name) AS content,
324
+ now() AS created_at,
325
+ now() AS updated_at
326
+ FROM movies
327
+ LEFT JOIN directors
328
+ ON directors.id = movies.director_id
329
+ SQL
330
+ end
331
+ end
332
+ ```
309
333
 
310
334
  #### Disabling multi-search indexing temporarily
311
335
 
@@ -314,9 +338,11 @@ records from an external source, you might want to speed things up by turning
314
338
  off indexing temporarily. You could then use one of the techniques above to
315
339
  rebuild the search documents off-line.
316
340
 
317
- PgSearch.disable_multisearch do
318
- Movie.import_from_xml_file(File.open("movies.xml"))
319
- end
341
+ ```ruby
342
+ PgSearch.disable_multisearch do
343
+ Movie.import_from_xml_file(File.open("movies.xml"))
344
+ end
345
+ ```
320
346
 
321
347
  ### pg_search_scope
322
348
 
@@ -329,34 +355,42 @@ search against.
329
355
 
330
356
  To search against a column, pass a symbol as the :against option.
331
357
 
332
- class BlogPost < ActiveRecord::Base
333
- include PgSearch
334
- pg_search_scope :search_by_title, :against => :title
335
- end
358
+ ```ruby
359
+ class BlogPost < ActiveRecord::Base
360
+ include PgSearch
361
+ pg_search_scope :search_by_title, :against => :title
362
+ end
363
+ ```
336
364
 
337
365
  We now have an ActiveRecord scope named search_by_title on our BlogPost model.
338
366
  It takes one parameter, a search query string.
339
367
 
340
- BlogPost.create!(:title => "Recent Developments in the World of Pastrami")
341
- BlogPost.create!(:title => "Prosciutto and You: A Retrospective")
342
- BlogPost.search_by_title("pastrami") # => [#<BlogPost id: 2, title: "Recent Developments in the World of Pastrami">]
368
+ ```ruby
369
+ BlogPost.create!(:title => "Recent Developments in the World of Pastrami")
370
+ BlogPost.create!(:title => "Prosciutto and You: A Retrospective")
371
+ BlogPost.search_by_title("pastrami") # => [#<BlogPost id: 2, title: "Recent Developments in the World of Pastrami">]
372
+ ```
343
373
 
344
374
  #### Searching against multiple columns
345
375
 
346
376
  Just pass an Array if you'd like to search more than one column.
347
377
 
348
- class Person < ActiveRecord::Base
349
- include PgSearch
350
- pg_search_scope :search_by_full_name, :against => [:first_name, :last_name]
351
- end
378
+ ```ruby
379
+ class Person < ActiveRecord::Base
380
+ include PgSearch
381
+ pg_search_scope :search_by_full_name, :against => [:first_name, :last_name]
382
+ end
383
+ ```
352
384
 
353
385
  Now our search query can match either or both of the columns.
354
386
 
355
- person_1 = Person.create!(:first_name => "Grant", :last_name => "Hill")
356
- person_2 = Person.create!(:first_name => "Hugh", :last_name => "Grant")
387
+ ```ruby
388
+ person_1 = Person.create!(:first_name => "Grant", :last_name => "Hill")
389
+ person_2 = Person.create!(:first_name => "Hugh", :last_name => "Grant")
357
390
 
358
- Person.search_by_full_name("Grant") # => [person_1, person_2]
359
- Person.search_by_full_name("Grant Hill") # => [person_1]
391
+ Person.search_by_full_name("Grant") # => [person_1, person_2]
392
+ Person.search_by_full_name("Grant Hill") # => [person_1]
393
+ ```
360
394
 
361
395
  #### Dynamic search scopes
362
396
 
@@ -368,22 +402,24 @@ Important: The returned hash must include a :query key. Its value does not
368
402
  necessary have to be dynamic. You could choose to hard-code it to a specific
369
403
  value if you wanted.
370
404
 
371
- class Person < ActiveRecord::Base
372
- include PgSearch
373
- pg_search_scope :search_by_name, lambda do |name_part, query|
374
- raise ArgumentError unless [:first, :last].include?(name_part)
375
- {
376
- :against => name_part,
377
- :query => query
378
- }
379
- end
380
- end
405
+ ```ruby
406
+ class Person < ActiveRecord::Base
407
+ include PgSearch
408
+ pg_search_scope :search_by_name, lambda do |name_part, query|
409
+ raise ArgumentError unless [:first, :last].include?(name_part)
410
+ {
411
+ :against => name_part,
412
+ :query => query
413
+ }
414
+ end
415
+ end
381
416
 
382
- person_1 = Person.create!(:first_name => "Grant", :last_name => "Hill")
383
- person_2 = Person.create!(:first_name => "Hugh", :last_name => "Grant")
417
+ person_1 = Person.create!(:first_name => "Grant", :last_name => "Hill")
418
+ person_2 = Person.create!(:first_name => "Hugh", :last_name => "Grant")
384
419
 
385
- Person.search_by_name :first, "Grant" # => [person_1]
386
- Person.search_by_name :last, "Grant" # => [person_2]
420
+ Person.search_by_name :first, "Grant" # => [person_1]
421
+ Person.search_by_name :last, "Grant" # => [person_2]
422
+ ```
387
423
 
388
424
  #### Searching through associations
389
425
 
@@ -406,38 +442,40 @@ works just like an :against option for the other model. Right now, searching
406
442
  deeper than one association away is not supported. You can work around this by
407
443
  setting up a series of :through associations to point all the way through.
408
444
 
409
- class Cracker < ActiveRecord::Base
410
- has_many :cheeses
411
- end
445
+ ```ruby
446
+ class Cracker < ActiveRecord::Base
447
+ has_many :cheeses
448
+ end
412
449
 
413
- class Cheese < ActiveRecord::Base
414
- end
450
+ class Cheese < ActiveRecord::Base
451
+ end
415
452
 
416
- class Salami < ActiveRecord::Base
417
- include PgSearch
453
+ class Salami < ActiveRecord::Base
454
+ include PgSearch
418
455
 
419
- belongs_to :cracker
420
- has_many :cheeses, :through => :cracker
456
+ belongs_to :cracker
457
+ has_many :cheeses, :through => :cracker
421
458
 
422
- pg_search_scope :tasty_search, :associated_against => {
423
- :cheeses => [:kind, :brand],
424
- :cracker => :kind
425
- }
426
- end
459
+ pg_search_scope :tasty_search, :associated_against => {
460
+ :cheeses => [:kind, :brand],
461
+ :cracker => :kind
462
+ }
463
+ end
427
464
 
428
- salami_1 = Salami.create!
429
- salami_2 = Salami.create!
430
- salami_3 = Salami.create!
465
+ salami_1 = Salami.create!
466
+ salami_2 = Salami.create!
467
+ salami_3 = Salami.create!
431
468
 
432
- limburger = Cheese.create!(:kind => "Limburger")
433
- brie = Cheese.create!(:kind => "Brie")
434
- pepper_jack = Cheese.create!(:kind => "Pepper Jack")
469
+ limburger = Cheese.create!(:kind => "Limburger")
470
+ brie = Cheese.create!(:kind => "Brie")
471
+ pepper_jack = Cheese.create!(:kind => "Pepper Jack")
435
472
 
436
- Cracker.create!(:kind => "Black Pepper", :cheeses => [brie], :salami => salami_1)
437
- Cracker.create!(:kind => "Ritz", :cheeses => [limburger, pepper_jack], :salami => salami_2)
438
- Cracker.create!(:kind => "Graham", :cheeses => [limburger], :salami => salami_3)
473
+ Cracker.create!(:kind => "Black Pepper", :cheeses => [brie], :salami => salami_1)
474
+ Cracker.create!(:kind => "Ritz", :cheeses => [limburger, pepper_jack], :salami => salami_2)
475
+ Cracker.create!(:kind => "Graham", :cheeses => [limburger], :salami => salami_3)
439
476
 
440
- Salami.tasty_search("pepper") # => [salami_1, salami_2]
477
+ Salami.tasty_search("pepper") # => [salami_1, salami_2]
478
+ ```
441
479
 
442
480
  ### Searching using different search features
443
481
 
@@ -446,10 +484,12 @@ search](http://www.postgresql.org/docs/current/static/textsearch-intro.html).
446
484
  If you pass the :using option to pg_search_scope, you can choose alternative
447
485
  search techniques.
448
486
 
449
- class Beer < ActiveRecord::Base
450
- include PgSearch
451
- pg_search_scope :search_name, :against => :name, :using => [:tsearch, :trigram, :dmetaphone]
452
- end
487
+ ```ruby
488
+ class Beer < ActiveRecord::Base
489
+ include PgSearch
490
+ pg_search_scope :search_name, :against => :name, :using => [:tsearch, :trigram, :dmetaphone]
491
+ end
492
+ ```
453
493
 
454
494
  The currently implemented features are
455
495
 
@@ -471,36 +511,40 @@ with earlier letters are weighted higher than those with later letters. So, in
471
511
  the following example, the title is the most important, followed by the
472
512
  subtitle, and finally the content.
473
513
 
474
- class NewsArticle < ActiveRecord::Base
475
- include PgSearch
476
- pg_search_scope :search_full_text, :against => {
477
- :title => 'A',
478
- :subtitle => 'B',
479
- :content => 'C'
480
- }
481
- end
514
+ ```ruby
515
+ class NewsArticle < ActiveRecord::Base
516
+ include PgSearch
517
+ pg_search_scope :search_full_text, :against => {
518
+ :title => 'A',
519
+ :subtitle => 'B',
520
+ :content => 'C'
521
+ }
522
+ end
523
+ ```
482
524
 
483
525
  You can also pass the weights in as an array of arrays, or any other structure
484
526
  that responds to #each and yields either a single symbol or a symbol and a
485
527
  weight. If you omit the weight, a default will be used.
486
528
 
487
- class NewsArticle < ActiveRecord::Base
488
- include PgSearch
489
- pg_search_scope :search_full_text, :against => [
490
- [:title, 'A'],
491
- [:subtitle, 'B'],
492
- [:content, 'C']
493
- ]
494
- end
495
-
496
- class NewsArticle < ActiveRecord::Base
497
- include PgSearch
498
- pg_search_scope :search_full_text, :against => [
499
- [:title, 'A'],
500
- {:subtitle => 'B'},
501
- :content
502
- ]
503
- end
529
+ ```ruby
530
+ class NewsArticle < ActiveRecord::Base
531
+ include PgSearch
532
+ pg_search_scope :search_full_text, :against => [
533
+ [:title, 'A'],
534
+ [:subtitle, 'B'],
535
+ [:content, 'C']
536
+ ]
537
+ end
538
+
539
+ class NewsArticle < ActiveRecord::Base
540
+ include PgSearch
541
+ pg_search_scope :search_full_text, :against => [
542
+ [:title, 'A'],
543
+ {:subtitle => 'B'},
544
+ :content
545
+ ]
546
+ end
547
+ ```
504
548
 
505
549
  ##### :prefix (PostgreSQL 8.4 and newer only)
506
550
 
@@ -509,20 +553,22 @@ to search for partial words, however, you can set :prefix to true. Since this
509
553
  is a :tsearch-specific option, you should pass it to :tsearch directly, as
510
554
  shown in the following example.
511
555
 
512
- class Superhero < ActiveRecord::Base
513
- include PgSearch
514
- pg_search_scope :whose_name_starts_with,
515
- :against => :name,
516
- :using => {
517
- :tsearch => {:prefix => true}
518
- }
519
- end
556
+ ```ruby
557
+ class Superhero < ActiveRecord::Base
558
+ include PgSearch
559
+ pg_search_scope :whose_name_starts_with,
560
+ :against => :name,
561
+ :using => {
562
+ :tsearch => {:prefix => true}
563
+ }
564
+ end
520
565
 
521
- batman = Superhero.create :name => 'Batman'
522
- batgirl = Superhero.create :name => 'Batgirl'
523
- robin = Superhero.create :name => 'Robin'
566
+ batman = Superhero.create :name => 'Batman'
567
+ batgirl = Superhero.create :name => 'Batgirl'
568
+ robin = Superhero.create :name => 'Robin'
524
569
 
525
- Superhero.whose_name_starts_with("Bat") # => [batman, batgirl]
570
+ Superhero.whose_name_starts_with("Bat") # => [batman, batgirl]
571
+ ```
526
572
 
527
573
  ##### :dictionary
528
574
 
@@ -535,26 +581,28 @@ you don't want stemming, you should pick the "simple" dictionary which does
535
581
  not do any stemming. If you don't specify a dictionary, the "simple"
536
582
  dictionary will be used.
537
583
 
538
- class BoringTweet < ActiveRecord::Base
539
- include PgSearch
540
- pg_search_scope :kinda_matching,
541
- :against => :text,
542
- :using => {
543
- :tsearch => {:dictionary => "english"}
544
- }
545
- pg_search_scope :literally_matching,
546
- :against => :text,
547
- :using => {
548
- :tsearch => {:dictionary => "simple"}
549
- }
550
- end
551
-
552
- sleepy = BoringTweet.create! :text => "I snoozed my alarm for fourteen hours today. I bet I can beat that tomorrow! #sleepy"
553
- sleeping = BoringTweet.create! :text => "You know what I like? Sleeping. That's what. #enjoyment"
554
- sleeper = BoringTweet.create! :text => "Have you seen Woody Allen's movie entitled Sleeper? Me neither. #boycott"
555
-
556
- BoringTweet.kinda_matching("sleeping") # => [sleepy, sleeping, sleeper]
557
- BoringTweet.literally_matching("sleeping") # => [sleeping]
584
+ ```ruby
585
+ class BoringTweet < ActiveRecord::Base
586
+ include PgSearch
587
+ pg_search_scope :kinda_matching,
588
+ :against => :text,
589
+ :using => {
590
+ :tsearch => {:dictionary => "english"}
591
+ }
592
+ pg_search_scope :literally_matching,
593
+ :against => :text,
594
+ :using => {
595
+ :tsearch => {:dictionary => "simple"}
596
+ }
597
+ end
598
+
599
+ sleepy = BoringTweet.create! :text => "I snoozed my alarm for fourteen hours today. I bet I can beat that tomorrow! #sleepy"
600
+ sleeping = BoringTweet.create! :text => "You know what I like? Sleeping. That's what. #enjoyment"
601
+ sleeper = BoringTweet.create! :text => "Have you seen Woody Allen's movie entitled Sleeper? Me neither. #boycott"
602
+
603
+ BoringTweet.kinda_matching("sleeping") # => [sleepy, sleeping, sleeper]
604
+ BoringTweet.literally_matching("sleeping") # => [sleeping]
605
+ ```
558
606
 
559
607
  ##### :normalization
560
608
 
@@ -577,46 +625,50 @@ This integer is a bitmask, so if you want to combine algorithms, you can add
577
625
  their numbers together.
578
626
  (e.g. to use algorithms 1, 8, and 32, you would pass 1 + 8 + 32 = 41)
579
627
 
580
- class BigLongDocument < ActiveRecord::Base
581
- include PgSearch
582
- pg_search_scope :regular_search,
583
- :against => :text
628
+ ```ruby
629
+ class BigLongDocument < ActiveRecord::Base
630
+ include PgSearch
631
+ pg_search_scope :regular_search,
632
+ :against => :text
584
633
 
585
- pg_search_scope :short_search,
586
- :against => :text,
587
- :using => {
588
- :tsearch => {:normalization => 2}
589
- }
634
+ pg_search_scope :short_search,
635
+ :against => :text,
636
+ :using => {
637
+ :tsearch => {:normalization => 2}
638
+ }
590
639
 
591
- long = BigLongDocument.create!(:text => "Four score and twenty years ago")
592
- short = BigLongDocument.create!(:text => "Four score")
640
+ long = BigLongDocument.create!(:text => "Four score and twenty years ago")
641
+ short = BigLongDocument.create!(:text => "Four score")
593
642
 
594
- BigLongDocument.regular_search("four score") #=> [long, short]
595
- BigLongDocument.short_search("four score") #=> [short, long]
643
+ BigLongDocument.regular_search("four score") #=> [long, short]
644
+ BigLongDocument.short_search("four score") #=> [short, long]
645
+ ```
596
646
 
597
647
  ##### :any_word
598
648
 
599
649
  Setting this attribute to true will perform a search which will return all
600
650
  models containing any word in the search terms.
601
651
 
602
- class Number < ActiveRecord::Base
603
- include PgSearch
604
- pg_search_scope :search_any_word,
605
- :against => :text,
606
- :using => {
607
- :tsearch => {:any_word => true}
608
- }
652
+ ```ruby
653
+ class Number < ActiveRecord::Base
654
+ include PgSearch
655
+ pg_search_scope :search_any_word,
656
+ :against => :text,
657
+ :using => {
658
+ :tsearch => {:any_word => true}
659
+ }
609
660
 
610
- pg_search_scope :search_all_words,
611
- :against => :text
612
- end
661
+ pg_search_scope :search_all_words,
662
+ :against => :text
663
+ end
613
664
 
614
- one = Number.create! :text => 'one'
615
- two = Number.create! :text => 'two'
616
- three = Number.create! :text => 'three'
665
+ one = Number.create! :text => 'one'
666
+ two = Number.create! :text => 'two'
667
+ three = Number.create! :text => 'three'
617
668
 
618
- Number.search_any_word('one two three') # => [one, two, three]
619
- Number.search_all_words('one two three') # => []
669
+ Number.search_any_word('one two three') # => [one, two, three]
670
+ Number.search_all_words('one two three') # => []
671
+ ```
620
672
 
621
673
  #### :dmetaphone (Double Metaphone soundalike search)
622
674
 
@@ -637,19 +689,21 @@ generate and run a migration for this, run:
637
689
 
638
690
  The following example shows how to use :dmetaphone.
639
691
 
640
- class Word < ActiveRecord::Base
641
- include PgSearch
642
- pg_search_scope :that_sounds_like,
643
- :against => :spelling,
644
- :using => :dmetaphone
645
- end
692
+ ```ruby
693
+ class Word < ActiveRecord::Base
694
+ include PgSearch
695
+ pg_search_scope :that_sounds_like,
696
+ :against => :spelling,
697
+ :using => :dmetaphone
698
+ end
646
699
 
647
- four = Word.create! :spelling => 'four'
648
- far = Word.create! :spelling => 'far'
649
- fur = Word.create! :spelling => 'fur'
650
- five = Word.create! :spelling => 'five'
700
+ four = Word.create! :spelling => 'four'
701
+ far = Word.create! :spelling => 'far'
702
+ fur = Word.create! :spelling => 'fur'
703
+ five = Word.create! :spelling => 'five'
651
704
 
652
- Word.that_sounds_like("fir") # => [four, far, fur]
705
+ Word.that_sounds_like("fir") # => [four, far, fur]
706
+ ```
653
707
 
654
708
  #### :trigram (Trigram search)
655
709
 
@@ -666,19 +720,21 @@ Trigram support is currently available as part of the [pg_trgm contrib
666
720
  package](http://www.postgresql.org/docs/current/static/pgtrgm.html) that must
667
721
  be installed before this feature can be used.
668
722
 
669
- class Website < ActiveRecord::Base
670
- include PgSearch
671
- pg_search_scope :kinda_spelled_like,
672
- :against => :name,
673
- :using => :trigram
674
- end
723
+ ```ruby
724
+ class Website < ActiveRecord::Base
725
+ include PgSearch
726
+ pg_search_scope :kinda_spelled_like,
727
+ :against => :name,
728
+ :using => :trigram
729
+ end
675
730
 
676
- yahooo = Website.create! :name => "Yahooo!"
677
- yohoo = Website.create! :name => "Yohoo!"
678
- gogle = Website.create! :name => "Gogle"
679
- facebook = Website.create! :name => "Facebook"
731
+ yahooo = Website.create! :name => "Yahooo!"
732
+ yohoo = Website.create! :name => "Yohoo!"
733
+ gogle = Website.create! :name => "Gogle"
734
+ facebook = Website.create! :name => "Facebook"
680
735
 
681
- Website.kinda_spelled_like("Yahoo!") # => [yahooo, yohoo]
736
+ Website.kinda_spelled_like("Yahoo!") # => [yahooo, yohoo]
737
+ ```
682
738
 
683
739
  ##### :threshold
684
740
 
@@ -687,34 +743,35 @@ using pg_trgm's calculations. You may specify a custom threshold if you prefer.
687
743
  Higher numbers match more strictly, and thus return fewer results. Lower numbers
688
744
  match more permissively, letting in more results.
689
745
 
690
- class Vegetable < ActiveRecord::Base
691
- include PgSearch
746
+ ```ruby
747
+ class Vegetable < ActiveRecord::Base
748
+ include PgSearch
692
749
 
693
- pg_search_scope :strictly_spelled_like,
694
- :against => :name,
695
- :using => {
696
- :trigram => {
697
- :threshold => 0.5
698
- }
699
- }
700
-
701
- pg_search_scope :roughly_spelled_like,
702
- :against => :name,
703
- :using => {
704
- :trigram => {
705
- :threshold => 0.1
706
- }
707
- }
708
- end
750
+ pg_search_scope :strictly_spelled_like,
751
+ :against => :name,
752
+ :using => {
753
+ :trigram => {
754
+ :threshold => 0.5
755
+ }
756
+ }
709
757
 
710
- cauliflower = Vegetable.create! :name => "cauliflower"
758
+ pg_search_scope :roughly_spelled_like,
759
+ :against => :name,
760
+ :using => {
761
+ :trigram => {
762
+ :threshold => 0.1
763
+ }
764
+ }
765
+ end
711
766
 
712
- Vegetable.roughly_spelled_like("couliflower") # => [cauliflower]
713
- Vegetable.strictly_spelled_like("couliflower") # => [cauliflower]
767
+ cauliflower = Vegetable.create! :name => "cauliflower"
714
768
 
715
- Vegetable.roughly_spelled_like("collyflower") # => [cauliflower]
716
- Vegetable.strictly_spelled_like("collyflower") # => []
769
+ Vegetable.roughly_spelled_like("couliflower") # => [cauliflower]
770
+ Vegetable.strictly_spelled_like("couliflower") # => [cauliflower]
717
771
 
772
+ Vegetable.roughly_spelled_like("collyflower") # => [cauliflower]
773
+ Vegetable.strictly_spelled_like("collyflower") # => []
774
+ ```
718
775
 
719
776
  ### Ignoring accent marks (PostgreSQL 9.0 and newer only)
720
777
 
@@ -727,19 +784,21 @@ Ignoring accents uses the [unaccent contrib
727
784
  package](http://www.postgresql.org/docs/current/static/unaccent.html) that
728
785
  must be installed before this feature can be used.
729
786
 
730
- class SpanishQuestion < ActiveRecord::Base
731
- include PgSearch
732
- pg_search_scope :gringo_search,
733
- :against => :word,
734
- :ignoring => :accents
735
- end
787
+ ```ruby
788
+ class SpanishQuestion < ActiveRecord::Base
789
+ include PgSearch
790
+ pg_search_scope :gringo_search,
791
+ :against => :word,
792
+ :ignoring => :accents
793
+ end
736
794
 
737
- what = SpanishQuestion.create(:word => "Qué")
738
- how_many = SpanishQuestion.create(:word => "Cuánto")
739
- how = SpanishQuestion.create(:word => "Cómo")
795
+ what = SpanishQuestion.create(:word => "Qué")
796
+ how_many = SpanishQuestion.create(:word => "Cuánto")
797
+ how = SpanishQuestion.create(:word => "Cómo")
740
798
 
741
- SpanishQuestion.gringo_search("Que") # => [what]
742
- SpanishQuestion.gringo_search("Cüåñtô") # => [how_many]
799
+ SpanishQuestion.gringo_search("Que") # => [what]
800
+ SpanishQuestion.gringo_search("Cüåñtô") # => [how_many]
801
+ ```
743
802
 
744
803
  Advanced users may wish to add indexes for the expressions that pg_search
745
804
  generates. Unfortunately, the unaccent function supplied by this contrib
@@ -747,7 +806,9 @@ package is not indexable (as of PostgreSQL 9.1). Thus, you may want to write
747
806
  your own wrapper function and use it instead. This can be configured by
748
807
  calling the following code, perhaps in an initializer.
749
808
 
750
- PgSearch.unaccent_function = "my_unaccent"
809
+ ```ruby
810
+ PgSearch.unaccent_function = "my_unaccent"
811
+ ```
751
812
 
752
813
  ### Using tsvector columns
753
814
 
@@ -800,21 +861,25 @@ By default, pg_search ranks results based on the :tsearch similarity between
800
861
  the searchable text and the query. To use a different ranking algorithm, you
801
862
  can pass a :ranked_by option to pg_search_scope.
802
863
 
803
- pg_search_scope :search_by_tsearch_but_rank_by_trigram,
804
- :against => :title,
805
- :using => [:tsearch],
806
- :ranked_by => ":trigram"
864
+ ```ruby
865
+ pg_search_scope :search_by_tsearch_but_rank_by_trigram,
866
+ :against => :title,
867
+ :using => [:tsearch],
868
+ :ranked_by => ":trigram"
869
+ ```
807
870
 
808
871
  Note that :ranked_by using a String to represent the ranking expression. This
809
872
  allows for more complex possibilities. Strings like ":tsearch", ":trigram",
810
873
  and ":dmetaphone" are automatically expanded into the appropriate SQL
811
874
  expressions.
812
875
 
813
- # Weighted ranking to balance multiple approaches
814
- :ranked_by => ":dmetaphone + (0.25 * :trigram)"
876
+ ```ruby
877
+ # Weighted ranking to balance multiple approaches
878
+ :ranked_by => ":dmetaphone + (0.25 * :trigram)"
815
879
 
816
- # A more complex example, where books.num_pages is an integer column in the table itself
817
- :ranked_by => "(books.num_pages * :trigram) + (:tsearch / 2.0)"
880
+ # A more complex example, where books.num_pages is an integer column in the table itself
881
+ :ranked_by => "(books.num_pages * :trigram) + (:tsearch / 2.0)"
882
+ ```
818
883
 
819
884
  #### :order_within_rank (Breaking ties)
820
885
 
@@ -843,9 +908,11 @@ want old records to outrank new records. By passing an :order_within_rank, you
843
908
  can specify an alternate tiebreaker expression. A common example would be
844
909
  descending by updated_at, to rank the most recently updated records first.
845
910
 
846
- pg_search_scope :search_and_break_ties_by_latest_update,
847
- :against => [:title, :content],
848
- :order_within_rank => "blog_posts.updated_at DESC"
911
+ ```ruby
912
+ pg_search_scope :search_and_break_ties_by_latest_update,
913
+ :against => [:title, :content],
914
+ :order_within_rank => "blog_posts.updated_at DESC"
915
+ ````
849
916
 
850
917
  #### PgSearch#pg_search_rank (Reading a record's rank as a Float)
851
918
 
@@ -854,9 +921,11 @@ can be helpful for debugging why one record outranks another. You could also
854
921
  use it to show some sort of relevancy value to end users of an application.
855
922
  Just call .pg_search_rank on a record returned by a pg_search_scope.
856
923
 
857
- shirt_brands = ShirtBrand.search_by_name("Penguin")
858
- shirt_brands[0].pg_search_rank #=> 0.0759909
859
- shirt_brands[1].pg_search_rank #=> 0.0607927
924
+ ```ruby
925
+ shirt_brands = ShirtBrand.search_by_name("Penguin")
926
+ shirt_brands[0].pg_search_rank #=> 0.0759909
927
+ shirt_brands[1].pg_search_rank #=> 0.0607927
928
+ ```
860
929
 
861
930
  ## ATTRIBUTIONS
862
931