pg_search 0.0.2 → 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -1
- data/CHANGELOG +6 -0
- data/README.rdoc +25 -4
- data/Rakefile +7 -0
- data/lib/pg_search/configuration.rb +8 -5
- data/lib/pg_search/normalizer.rb +1 -1
- data/lib/pg_search/version.rb +1 -1
- data/spec/associations_spec.rb +37 -0
- data/spec/pg_search_spec.rb +16 -16
- metadata +4 -5
data/.gitignore
CHANGED
data/CHANGELOG
CHANGED
data/README.rdoc
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
* http://github.com/casecommons/pg_search/
|
4
4
|
|
5
|
-
== DESCRIPTION
|
5
|
+
== DESCRIPTION
|
6
6
|
|
7
7
|
PgSearch builds named scopes that take advantage of PostgreSQL's full text search
|
8
8
|
|
9
|
-
== INSTALL
|
9
|
+
== INSTALL
|
10
10
|
|
11
11
|
gem install pg_search
|
12
12
|
|
@@ -99,10 +99,10 @@ Important: The returned hash must include a :query key. Its value does not neces
|
|
99
99
|
You can pass a Hash into the :associated_against option to search columns on other models. The keys are the names of the associations and the value works just like an :against option for the other model.
|
100
100
|
|
101
101
|
class Cracker < ActiveRecord::Base
|
102
|
+
has_many :cheeses
|
102
103
|
end
|
103
104
|
|
104
105
|
class Cheese < ActiveRecord::Base
|
105
|
-
has_many :cheeses
|
106
106
|
end
|
107
107
|
|
108
108
|
class Salami < ActiveRecord::Base
|
@@ -279,12 +279,33 @@ Trigram support is currently available as part of the {pg_trgm contrib package}[
|
|
279
279
|
|
280
280
|
Website.kinda_spelled_like("Yahoo!") # => [yahooo, yohoo]
|
281
281
|
|
282
|
+
=== Ignoring accent marks
|
283
|
+
|
284
|
+
Most of the time you will want to ignore accent marks when searching. This makes it possible to find words like "piñata" when searching with the query "pinata". If you set a pg_search_scope to ignore accents, it will ignore accents in both the searchable text and the query terms.
|
285
|
+
|
286
|
+
Ignoring accents uses the {unaccent contrib package}[http://www.postgresql.org/docs/current/static/unaccent.html] that must be installed before this feature can be used.
|
287
|
+
|
288
|
+
|
289
|
+
class SpanishQuestion < ActiveRecord::Base
|
290
|
+
include PgSearch
|
291
|
+
pg_search_scope :gringo_search,
|
292
|
+
:against => :word,
|
293
|
+
:ignoring => :accents
|
294
|
+
end
|
295
|
+
|
296
|
+
what = SpanishQuestion.create(:word => "Qué")
|
297
|
+
how_many = SpanishQuestion.create(:word => "Cuánto")
|
298
|
+
how = SpanishQuestion.create(:word => "Cómo")
|
299
|
+
|
300
|
+
SpanishQuestion.gringo_search("Que") # => [what]
|
301
|
+
SpanishQuestion.gringo_search("Cüåñtô") # => [how_many]
|
302
|
+
|
282
303
|
== REQUIREMENTS
|
283
304
|
|
284
305
|
* ActiveRecord 2 or 3
|
285
306
|
* Postgresql
|
286
307
|
* Postgresql contrib modules for certain features
|
287
308
|
|
288
|
-
== LICENSE
|
309
|
+
== LICENSE
|
289
310
|
|
290
311
|
MIT
|
data/Rakefile
CHANGED
@@ -14,6 +14,7 @@ module PgSearch
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def regular_columns
|
17
|
+
return [] unless @options[:against]
|
17
18
|
Array(@options[:against]).map do |column_name, weight|
|
18
19
|
Column.new(column_name, weight, @model)
|
19
20
|
end
|
@@ -32,8 +33,8 @@ module PgSearch
|
|
32
33
|
@options[:query].to_s
|
33
34
|
end
|
34
35
|
|
35
|
-
def
|
36
|
-
Array.wrap(@options[:
|
36
|
+
def ignore
|
37
|
+
Array.wrap(@options[:ignoring])
|
37
38
|
end
|
38
39
|
|
39
40
|
def ranking_sql
|
@@ -51,12 +52,14 @@ module PgSearch
|
|
51
52
|
end
|
52
53
|
|
53
54
|
def assert_valid_options(options)
|
54
|
-
valid_keys = [:against, :ranked_by, :
|
55
|
+
valid_keys = [:against, :ranked_by, :ignoring, :using, :query, :associated_against]
|
55
56
|
valid_values = {
|
56
|
-
:
|
57
|
+
:ignoring => [:accents]
|
57
58
|
}
|
58
59
|
|
59
|
-
|
60
|
+
unless options[:against] || options[:associated_against]
|
61
|
+
raise ArgumentError, "the search scope #{@name} must have :against#{" or :associated_against" if defined?(ActiveRecord::Relation)} in its options"
|
62
|
+
end
|
60
63
|
raise ArgumentError, ":associated_against requires ActiveRecord 3 or later" if options[:associated_against] && !defined?(ActiveRecord::Relation)
|
61
64
|
|
62
65
|
options.assert_valid_keys(valid_keys)
|
data/lib/pg_search/normalizer.rb
CHANGED
@@ -6,7 +6,7 @@ module PgSearch
|
|
6
6
|
|
7
7
|
def add_normalization(original_sql)
|
8
8
|
normalized_sql = original_sql
|
9
|
-
normalized_sql = "unaccent(#{normalized_sql})" if @config.
|
9
|
+
normalized_sql = "unaccent(#{normalized_sql})" if @config.ignore.include?(:accents)
|
10
10
|
normalized_sql
|
11
11
|
end
|
12
12
|
end
|
data/lib/pg_search/version.rb
CHANGED
data/spec/associations_spec.rb
CHANGED
@@ -4,6 +4,43 @@ describe PgSearch do
|
|
4
4
|
context "joining to another table" do
|
5
5
|
if defined?(ActiveRecord::Relation)
|
6
6
|
context "with Arel support" do
|
7
|
+
context "without an :against" do
|
8
|
+
with_model :associated_model do
|
9
|
+
table do |t|
|
10
|
+
t.string "title"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
with_model :model_without_against do
|
15
|
+
table do |t|
|
16
|
+
t.string "title"
|
17
|
+
t.belongs_to :another_model
|
18
|
+
end
|
19
|
+
|
20
|
+
model do
|
21
|
+
include PgSearch
|
22
|
+
belongs_to :another_model, :class_name => 'AssociatedModel'
|
23
|
+
|
24
|
+
pg_search_scope :with_another, :associated_against => {:another_model => :title}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it "returns rows that match the query in the columns of the associated model only" do
|
29
|
+
associated = associated_model.create!(:title => 'abcdef')
|
30
|
+
included = [
|
31
|
+
model_without_against.create!(:title => 'abcdef', :another_model => associated),
|
32
|
+
model_without_against.create!(:title => 'ghijkl', :another_model => associated)
|
33
|
+
]
|
34
|
+
excluded = [
|
35
|
+
model_without_against.create!(:title => 'abcdef')
|
36
|
+
]
|
37
|
+
|
38
|
+
results = model_without_against.with_another('abcdef')
|
39
|
+
results.map(&:title).should =~ included.map(&:title)
|
40
|
+
results.should_not include(excluded)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
7
44
|
context "through a belongs_to association" do
|
8
45
|
with_model :associated_model do
|
9
46
|
table do |t|
|
data/spec/pg_search_spec.rb
CHANGED
@@ -88,24 +88,24 @@ describe "an ActiveRecord model which includes PgSearch" do
|
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
91
|
-
context "when an unknown :
|
91
|
+
context "when an unknown :ignoring is passed" do
|
92
92
|
it "raises an exception when invoked" do
|
93
93
|
lambda {
|
94
94
|
model_with_pg_search.class_eval do
|
95
|
-
pg_search_scope :
|
95
|
+
pg_search_scope :with_unknown_ignoring, :against => :content, :ignoring => :foo
|
96
96
|
end
|
97
|
-
model_with_pg_search.
|
98
|
-
}.should raise_error(ArgumentError, /
|
97
|
+
model_with_pg_search.with_unknown_ignoring("foo")
|
98
|
+
}.should raise_error(ArgumentError, /ignoring.*foo/)
|
99
99
|
end
|
100
100
|
|
101
101
|
context "dynamically" do
|
102
102
|
it "raises an exception when invoked" do
|
103
103
|
lambda {
|
104
104
|
model_with_pg_search.class_eval do
|
105
|
-
pg_search_scope :
|
105
|
+
pg_search_scope :with_unknown_ignoring, lambda { |*| {:against => :content, :ignoring => :foo} }
|
106
106
|
end
|
107
|
-
model_with_pg_search.
|
108
|
-
}.should raise_error(ArgumentError, /
|
107
|
+
model_with_pg_search.with_unknown_ignoring("foo")
|
108
|
+
}.should raise_error(ArgumentError, /ignoring.*foo/)
|
109
109
|
end
|
110
110
|
end
|
111
111
|
|
@@ -113,18 +113,18 @@ describe "an ActiveRecord model which includes PgSearch" do
|
|
113
113
|
it "raises an exception when invoked" do
|
114
114
|
lambda {
|
115
115
|
model_with_pg_search.class_eval do
|
116
|
-
pg_search_scope :
|
116
|
+
pg_search_scope :with_unknown_ignoring, {}
|
117
117
|
end
|
118
|
-
model_with_pg_search.
|
118
|
+
model_with_pg_search.with_unknown_ignoring("foo")
|
119
119
|
}.should raise_error(ArgumentError, /against/)
|
120
120
|
end
|
121
121
|
context "dynamically" do
|
122
122
|
it "raises an exception when invoked" do
|
123
123
|
lambda {
|
124
124
|
model_with_pg_search.class_eval do
|
125
|
-
pg_search_scope :
|
125
|
+
pg_search_scope :with_unknown_ignoring, lambda { |*| {} }
|
126
126
|
end
|
127
|
-
model_with_pg_search.
|
127
|
+
model_with_pg_search.with_unknown_ignoring("foo")
|
128
128
|
}.should raise_error(ArgumentError, /against/)
|
129
129
|
end
|
130
130
|
end
|
@@ -177,7 +177,7 @@ describe "an ActiveRecord model which includes PgSearch" do
|
|
177
177
|
results.should =~ included
|
178
178
|
end
|
179
179
|
|
180
|
-
it "returns rows that match the query only if their
|
180
|
+
it "returns rows that match the query only if their accents match" do
|
181
181
|
# \303\241 is a with acute accent
|
182
182
|
# \303\251 is e with acute accent
|
183
183
|
|
@@ -513,20 +513,20 @@ describe "an ActiveRecord model which includes PgSearch" do
|
|
513
513
|
end
|
514
514
|
end
|
515
515
|
|
516
|
-
context "
|
516
|
+
context "ignoring accents" do
|
517
517
|
before do
|
518
518
|
model_with_pg_search.class_eval do
|
519
|
-
pg_search_scope :
|
519
|
+
pg_search_scope :search_title_without_accents, :against => :title, :ignoring => :accents
|
520
520
|
end
|
521
521
|
end
|
522
522
|
|
523
|
-
it "returns rows that match the query but not its
|
523
|
+
it "returns rows that match the query but not its accents" do
|
524
524
|
# \303\241 is a with acute accent
|
525
525
|
# \303\251 is e with acute accent
|
526
526
|
|
527
527
|
included = model_with_pg_search.create!(:title => "\303\241bcdef")
|
528
528
|
|
529
|
-
results = model_with_pg_search.
|
529
|
+
results = model_with_pg_search.search_title_without_accents("abcd\303\251f")
|
530
530
|
results.should == [included]
|
531
531
|
end
|
532
532
|
end
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pg_search
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 9
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
|
10
|
-
version: 0.0.2
|
8
|
+
- 1
|
9
|
+
version: "0.1"
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Case Commons, LLC
|
@@ -15,7 +14,7 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date: 2011-01-
|
17
|
+
date: 2011-01-18 00:00:00 -05:00
|
19
18
|
default_executable:
|
20
19
|
dependencies: []
|
21
20
|
|