pg_search 0.5.4 → 0.5.5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +6 -0
- data/README.rdoc +4 -0
- data/lib/pg_search.rb +16 -2
- data/lib/pg_search/configuration.rb +16 -18
- data/lib/pg_search/document.rb +1 -1
- data/lib/pg_search/features/dmetaphone.rb +12 -4
- data/lib/pg_search/features/feature.rb +6 -4
- data/lib/pg_search/features/trigram.rb +2 -2
- data/lib/pg_search/features/tsearch.rb +12 -12
- data/lib/pg_search/multisearch/rebuilder.rb +21 -19
- data/lib/pg_search/normalizer.rb +8 -4
- data/lib/pg_search/scope_options.rb +13 -12
- data/lib/pg_search/version.rb +1 -1
- data/spec/pg_search/document_spec.rb +1 -1
- data/spec/pg_search/normalizer_spec.rb +58 -0
- data/spec/pg_search_spec.rb +44 -0
- metadata +6 -5
- data/lib/pg_search/scope.rb +0 -27
data/CHANGELOG.rdoc
CHANGED
data/README.rdoc
CHANGED
@@ -495,6 +495,10 @@ Ignoring accents uses the {unaccent contrib package}[http://www.postgresql.org/d
|
|
495
495
|
SpanishQuestion.gringo_search("Que") # => [what]
|
496
496
|
SpanishQuestion.gringo_search("Cüåñtô") # => [how_many]
|
497
497
|
|
498
|
+
Advanced users may wish to add indexes for the expressions that pg_search generates. Unfortunately, the unaccent function supplied by this contrib package is not indexable (as of PostgreSQL 9.1). Thus, you may want to write your own wrapper function and use it instead. This can be configured by calling the following code, perhaps in an initializer.
|
499
|
+
|
500
|
+
PgSearch.unaccent_function = "my_unaccent"
|
501
|
+
|
498
502
|
=== Using tsvector columns
|
499
503
|
|
500
504
|
PostgreSQL allows you the ability to search against a column with type tsvector instead of using an expression; this speeds up searching dramatically as it offloads creation of the tsvector that the tsquery is evaluated against.
|
data/lib/pg_search.rb
CHANGED
@@ -18,11 +18,25 @@ module PgSearch
|
|
18
18
|
mattr_accessor :multisearch_options
|
19
19
|
self.multisearch_options = {}
|
20
20
|
|
21
|
+
mattr_accessor :unaccent_function
|
22
|
+
self.unaccent_function = "unaccent"
|
23
|
+
|
21
24
|
module ClassMethods
|
22
25
|
def pg_search_scope(name, options)
|
23
|
-
|
26
|
+
options_proc = if options.respond_to?(:call)
|
27
|
+
options
|
28
|
+
else
|
29
|
+
unless options.respond_to?(:merge)
|
30
|
+
raise ArgumentError, "pg_search_scope expects a Hash or Proc"
|
31
|
+
end
|
32
|
+
lambda { |query| {:query => query}.merge(options) }
|
33
|
+
end
|
24
34
|
|
25
|
-
method_proc =
|
35
|
+
method_proc = lambda do |*args|
|
36
|
+
config = Configuration.new(options_proc.call(*args), self)
|
37
|
+
scope_options = ScopeOptions.new(config)
|
38
|
+
scope_options.apply(self)
|
39
|
+
end
|
26
40
|
|
27
41
|
if respond_to?(:define_singleton_method)
|
28
42
|
define_singleton_method name, &method_proc
|
@@ -15,7 +15,7 @@ module PgSearch
|
|
15
15
|
|
16
16
|
class << self
|
17
17
|
def alias(*strings)
|
18
|
-
name = Array
|
18
|
+
name = Array(strings).compact.join("_")
|
19
19
|
# By default, PostgreSQL limits names to 32 characters, so we hash and limit to 32 characters.
|
20
20
|
"pg_search_#{Digest::SHA2.hexdigest(name)}"[0,32]
|
21
21
|
end
|
@@ -26,16 +26,16 @@ module PgSearch
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def regular_columns
|
29
|
-
return [] unless
|
30
|
-
Array(
|
31
|
-
Column.new(column_name, weight,
|
29
|
+
return [] unless options[:against]
|
30
|
+
Array(options[:against]).map do |column_name, weight|
|
31
|
+
Column.new(column_name, weight, model)
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
35
|
def associations
|
36
|
-
return [] unless
|
37
|
-
|
38
|
-
Association.new(
|
36
|
+
return [] unless options[:associated_against]
|
37
|
+
options[:associated_against].map do |association, column_names|
|
38
|
+
Association.new(model, association, column_names)
|
39
39
|
end.flatten
|
40
40
|
end
|
41
41
|
|
@@ -44,35 +44,33 @@ module PgSearch
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def query
|
47
|
-
|
47
|
+
options[:query].to_s
|
48
48
|
end
|
49
49
|
|
50
50
|
def ignore
|
51
|
-
Array
|
51
|
+
Array(options[:ignoring])
|
52
52
|
end
|
53
53
|
|
54
54
|
def ranking_sql
|
55
|
-
|
55
|
+
options[:ranked_by]
|
56
56
|
end
|
57
57
|
|
58
58
|
def features
|
59
|
-
Array(
|
59
|
+
Array(options[:using])
|
60
60
|
end
|
61
61
|
|
62
62
|
def order_within_rank
|
63
|
-
|
63
|
+
options[:order_within_rank]
|
64
64
|
end
|
65
65
|
|
66
66
|
def postgresql_version
|
67
|
-
|
68
|
-
end
|
69
|
-
|
70
|
-
def logger
|
71
|
-
@model.logger
|
67
|
+
model.connection.send(:postgresql_version)
|
72
68
|
end
|
73
69
|
|
74
70
|
private
|
75
71
|
|
72
|
+
attr_reader :options
|
73
|
+
|
76
74
|
def default_options
|
77
75
|
{:using => :tsearch}
|
78
76
|
end
|
@@ -97,7 +95,7 @@ module PgSearch
|
|
97
95
|
options.assert_valid_keys(VALID_KEYS)
|
98
96
|
|
99
97
|
VALID_VALUES.each do |key, values_for_key|
|
100
|
-
Array
|
98
|
+
Array(options[key]).each do |value|
|
101
99
|
unless values_for_key.include?(value)
|
102
100
|
raise ArgumentError, ":#{key} cannot accept #{value}"
|
103
101
|
end
|
data/lib/pg_search/document.rb
CHANGED
@@ -27,7 +27,7 @@ module PgSearch
|
|
27
27
|
private
|
28
28
|
|
29
29
|
def update_content
|
30
|
-
methods = Array
|
30
|
+
methods = Array(searchable.pg_search_multisearchable_options[:against])
|
31
31
|
searchable_text = methods.map { |symbol| searchable.send(symbol) }.join(" ")
|
32
32
|
self.content = searchable_text
|
33
33
|
end
|
@@ -8,23 +8,31 @@ module PgSearch
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def conditions
|
11
|
-
|
11
|
+
tsearch.conditions
|
12
12
|
end
|
13
13
|
|
14
14
|
def rank
|
15
|
-
|
15
|
+
tsearch.rank
|
16
16
|
end
|
17
17
|
|
18
|
+
private
|
19
|
+
|
20
|
+
attr_reader :tsearch
|
21
|
+
|
18
22
|
# Decorates a normalizer with dmetaphone processing.
|
19
23
|
class Normalizer
|
20
24
|
def initialize(normalizer_to_wrap)
|
21
|
-
@
|
25
|
+
@normalizer_to_wrap = normalizer_to_wrap
|
22
26
|
end
|
23
27
|
|
24
28
|
def add_normalization(original_sql)
|
25
|
-
otherwise_normalized_sql =
|
29
|
+
otherwise_normalized_sql = normalizer_to_wrap.add_normalization(original_sql)
|
26
30
|
"pg_search_dmetaphone(#{otherwise_normalized_sql})"
|
27
31
|
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
attr_reader :normalizer_to_wrap
|
28
36
|
end
|
29
37
|
end
|
30
38
|
end
|
@@ -11,17 +11,19 @@ module PgSearch
|
|
11
11
|
|
12
12
|
private
|
13
13
|
|
14
|
+
attr_reader :query, :options, :columns, :model, :normalizer
|
15
|
+
|
14
16
|
def document
|
15
|
-
if
|
16
|
-
|
17
|
+
if columns.length == 1
|
18
|
+
columns.first.to_sql
|
17
19
|
else
|
18
|
-
expressions =
|
20
|
+
expressions = columns.map { |column| column.to_sql }.join(", ")
|
19
21
|
"array_to_string(ARRAY[#{expressions}], ' ')"
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
23
25
|
def normalize(expression)
|
24
|
-
|
26
|
+
normalizer.add_normalization(expression)
|
25
27
|
end
|
26
28
|
end
|
27
29
|
end
|
@@ -4,14 +4,14 @@ module PgSearch
|
|
4
4
|
def conditions
|
5
5
|
[
|
6
6
|
"(#{normalize(document)}) % #{normalize(":query")}",
|
7
|
-
{:query =>
|
7
|
+
{:query => query}
|
8
8
|
]
|
9
9
|
end
|
10
10
|
|
11
11
|
def rank
|
12
12
|
[
|
13
13
|
"similarity((#{normalize(document)}), #{normalize(":query")})",
|
14
|
-
{:query =>
|
14
|
+
{:query => query}
|
15
15
|
]
|
16
16
|
end
|
17
17
|
end
|
@@ -5,10 +5,10 @@ module PgSearch
|
|
5
5
|
class TSearch < Feature
|
6
6
|
delegate :connection, :quoted_table_name, :to => :'@model'
|
7
7
|
|
8
|
-
def initialize(
|
8
|
+
def initialize(*args)
|
9
9
|
super
|
10
10
|
|
11
|
-
if
|
11
|
+
if options[:prefix] && model.connection.send(:postgresql_version) < 80400
|
12
12
|
raise PgSearch::NotSupportedForPostgresqlVersion.new(<<-MESSAGE.gsub /^\s*/, '')
|
13
13
|
Sorry, {:using => {:tsearch => {:prefix => true}}} only works in PostgreSQL 8.4 and above.")
|
14
14
|
MESSAGE
|
@@ -26,7 +26,7 @@ module PgSearch
|
|
26
26
|
private
|
27
27
|
|
28
28
|
def interpolations
|
29
|
-
{:query =>
|
29
|
+
{:query => query.to_s, :dictionary => dictionary.to_s}
|
30
30
|
end
|
31
31
|
|
32
32
|
DISALLOWED_TSQUERY_CHARACTERS = /['?\\:]/
|
@@ -42,25 +42,25 @@ module PgSearch
|
|
42
42
|
connection.quote("' "),
|
43
43
|
term_sql,
|
44
44
|
connection.quote(" '"),
|
45
|
-
(connection.quote(':*') if
|
45
|
+
(connection.quote(':*') if options[:prefix])
|
46
46
|
].compact.join(" || ")
|
47
47
|
|
48
48
|
"to_tsquery(:dictionary, #{tsquery_sql})"
|
49
49
|
end
|
50
50
|
|
51
51
|
def tsquery
|
52
|
-
return "''" if
|
53
|
-
query_terms =
|
52
|
+
return "''" if query.blank?
|
53
|
+
query_terms = query.split(" ").compact
|
54
54
|
tsquery_terms = query_terms.map { |term| tsquery_for_term(term) }
|
55
|
-
tsquery_terms.join(
|
55
|
+
tsquery_terms.join(options[:any_word] ? ' || ' : ' && ')
|
56
56
|
end
|
57
57
|
|
58
58
|
def tsdocument
|
59
|
-
if
|
60
|
-
column_name = connection.quote_column_name(
|
59
|
+
if options[:tsvector_column]
|
60
|
+
column_name = connection.quote_column_name(options[:tsvector_column])
|
61
61
|
"#{quoted_table_name}.#{column_name}"
|
62
62
|
else
|
63
|
-
|
63
|
+
columns.map do |search_column|
|
64
64
|
tsvector = "to_tsvector(:dictionary, #{normalize(search_column.to_sql)})"
|
65
65
|
if search_column.weight.nil?
|
66
66
|
tsvector
|
@@ -81,7 +81,7 @@ module PgSearch
|
|
81
81
|
# 32 divides the rank by itself + 1
|
82
82
|
# The integer option controls several behaviors, so it is a bit mask: you can specify one or more behaviors
|
83
83
|
def normalization
|
84
|
-
|
84
|
+
options[:normalization] || 0
|
85
85
|
end
|
86
86
|
|
87
87
|
def tsearch_rank
|
@@ -89,7 +89,7 @@ module PgSearch
|
|
89
89
|
end
|
90
90
|
|
91
91
|
def dictionary
|
92
|
-
|
92
|
+
options[:dictionary] || :simple
|
93
93
|
end
|
94
94
|
end
|
95
95
|
end
|
@@ -1,18 +1,6 @@
|
|
1
1
|
module PgSearch
|
2
2
|
module Multisearch
|
3
3
|
class Rebuilder
|
4
|
-
REBUILD_SQL_TEMPLATE = <<-SQL
|
5
|
-
INSERT INTO :documents_table (searchable_type, searchable_id, content, created_at, updated_at)
|
6
|
-
SELECT :model_name AS searchable_type,
|
7
|
-
:model_table.id AS searchable_id,
|
8
|
-
(
|
9
|
-
:content_expressions
|
10
|
-
) AS content,
|
11
|
-
:current_time AS created_at,
|
12
|
-
:current_time AS updated_at
|
13
|
-
FROM :model_table
|
14
|
-
SQL
|
15
|
-
|
16
4
|
def initialize(model)
|
17
5
|
unless model.respond_to?(:pg_search_multisearchable_options)
|
18
6
|
raise ModelNotMultisearchable.new(model)
|
@@ -22,19 +10,33 @@ SQL
|
|
22
10
|
end
|
23
11
|
|
24
12
|
def rebuild
|
25
|
-
if
|
26
|
-
|
13
|
+
if model.respond_to?(:rebuild_pg_search_documents)
|
14
|
+
model.rebuild_pg_search_documents
|
27
15
|
else
|
28
|
-
|
16
|
+
model.connection.execute(rebuild_sql)
|
29
17
|
end
|
30
18
|
end
|
31
19
|
|
32
20
|
private
|
33
21
|
|
22
|
+
attr_reader :model
|
23
|
+
|
34
24
|
def connection
|
35
|
-
|
25
|
+
model.connection
|
36
26
|
end
|
37
27
|
|
28
|
+
REBUILD_SQL_TEMPLATE = <<-SQL
|
29
|
+
INSERT INTO :documents_table (searchable_type, searchable_id, content, created_at, updated_at)
|
30
|
+
SELECT :model_name AS searchable_type,
|
31
|
+
:model_table.id AS searchable_id,
|
32
|
+
(
|
33
|
+
:content_expressions
|
34
|
+
) AS content,
|
35
|
+
:current_time AS created_at,
|
36
|
+
:current_time AS updated_at
|
37
|
+
FROM :model_table
|
38
|
+
SQL
|
39
|
+
|
38
40
|
def rebuild_sql
|
39
41
|
replacements.inject(REBUILD_SQL_TEMPLATE) do |sql, key|
|
40
42
|
sql.gsub ":#{key}", send(key)
|
@@ -52,15 +54,15 @@ SQL
|
|
52
54
|
end
|
53
55
|
|
54
56
|
def columns
|
55
|
-
Array
|
57
|
+
Array(model.pg_search_multisearchable_options[:against])
|
56
58
|
end
|
57
59
|
|
58
60
|
def model_name
|
59
|
-
connection.quote(
|
61
|
+
connection.quote(model.name)
|
60
62
|
end
|
61
63
|
|
62
64
|
def model_table
|
63
|
-
|
65
|
+
model.quoted_table_name
|
64
66
|
end
|
65
67
|
|
66
68
|
def documents_table
|
data/lib/pg_search/normalizer.rb
CHANGED
@@ -5,18 +5,22 @@ module PgSearch
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def add_normalization(sql_expression)
|
8
|
-
if
|
9
|
-
if
|
8
|
+
if config.ignore.include?(:accents)
|
9
|
+
if config.postgresql_version < 90000
|
10
10
|
raise PgSearch::NotSupportedForPostgresqlVersion.new(<<-MESSAGE.gsub /^\s*/, '')
|
11
11
|
Sorry, {:ignoring => :accents} only works in PostgreSQL 9.0 and above.
|
12
|
-
#{
|
12
|
+
#{config.inspect}
|
13
13
|
MESSAGE
|
14
14
|
else
|
15
|
-
"
|
15
|
+
"#{PgSearch.unaccent_function}(#{sql_expression})"
|
16
16
|
end
|
17
17
|
else
|
18
18
|
sql_expression
|
19
19
|
end
|
20
20
|
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
attr_reader :config
|
21
25
|
end
|
22
26
|
end
|
@@ -2,10 +2,9 @@ require "active_support/core_ext/module/delegation"
|
|
2
2
|
|
3
3
|
module PgSearch
|
4
4
|
class ScopeOptions
|
5
|
-
|
5
|
+
attr_reader :config, :feature_options
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
@name = name
|
7
|
+
def initialize(config)
|
9
8
|
@config = config
|
10
9
|
@model = config.model
|
11
10
|
@feature_options = Hash[config.features]
|
@@ -17,14 +16,16 @@ module PgSearch
|
|
17
16
|
|
18
17
|
private
|
19
18
|
|
19
|
+
delegate :connection, :quoted_table_name, :sanitize_sql_array, :to => :@model
|
20
|
+
|
20
21
|
def conditions
|
21
|
-
|
22
|
+
config.features.map do |feature_name, feature_options|
|
22
23
|
"(#{sanitize_sql_array(feature_for(feature_name).conditions)})"
|
23
24
|
end.join(" OR ")
|
24
25
|
end
|
25
26
|
|
26
27
|
def order_within_rank
|
27
|
-
|
28
|
+
config.order_within_rank || "#{primary_key} ASC"
|
28
29
|
end
|
29
30
|
|
30
31
|
def primary_key
|
@@ -32,7 +33,7 @@ module PgSearch
|
|
32
33
|
end
|
33
34
|
|
34
35
|
def joins
|
35
|
-
|
36
|
+
config.associations.map do |association|
|
36
37
|
association.join(primary_key)
|
37
38
|
end.join(' ')
|
38
39
|
end
|
@@ -49,19 +50,19 @@ module PgSearch
|
|
49
50
|
|
50
51
|
raise ArgumentError.new("Unknown feature: #{feature_name}") unless feature_class
|
51
52
|
|
52
|
-
normalizer = Normalizer.new(
|
53
|
+
normalizer = Normalizer.new(config)
|
53
54
|
|
54
55
|
feature_class.new(
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
56
|
+
config.query,
|
57
|
+
feature_options[feature_name],
|
58
|
+
config.columns,
|
59
|
+
config.model,
|
59
60
|
normalizer
|
60
61
|
)
|
61
62
|
end
|
62
63
|
|
63
64
|
def rank
|
64
|
-
(
|
65
|
+
(config.ranking_sql || ":tsearch").gsub(/:(\w*)/) do
|
65
66
|
sanitize_sql_array(feature_for($1).rank)
|
66
67
|
end
|
67
68
|
end
|
data/lib/pg_search/version.rb
CHANGED
@@ -0,0 +1,58 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe PgSearch::Normalizer do
|
4
|
+
describe "#add_normalization" do
|
5
|
+
context "for PostgreSQL 9.0 and above" do
|
6
|
+
context "when config[:ignore] includes :accents" do
|
7
|
+
it "wraps the expression in unaccent()" do
|
8
|
+
config = stub("config", :ignore => [:accents], :postgresql_version => 90000)
|
9
|
+
|
10
|
+
normalizer = PgSearch::Normalizer.new(config)
|
11
|
+
normalizer.add_normalization("foo").should == "unaccent(foo)"
|
12
|
+
end
|
13
|
+
|
14
|
+
context "when a custom unaccent function is specified" do
|
15
|
+
it "wraps the expression in that function" do
|
16
|
+
PgSearch.stub(:unaccent_function).and_return("my_unaccent")
|
17
|
+
|
18
|
+
config = stub("config", :ignore => [:accents], :postgresql_version => 90000)
|
19
|
+
|
20
|
+
normalizer = PgSearch::Normalizer.new(config)
|
21
|
+
normalizer.add_normalization("foo").should == "my_unaccent(foo)"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "when config[:ignore] does not include :accents" do
|
27
|
+
it "passes the expression through" do
|
28
|
+
config = stub("config", :ignore => [], :postgresql_version => 90000)
|
29
|
+
|
30
|
+
normalizer = PgSearch::Normalizer.new(config)
|
31
|
+
normalizer.add_normalization("foo").should == "foo"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "for PostgreSQL versions before 9.0" do
|
37
|
+
context "when config[:ignore] includes :accents" do
|
38
|
+
it "raises a NotSupportedForPostgresqlVersion exception" do
|
39
|
+
config = stub("config", :ignore => [:accents], :postgresql_version => 89999)
|
40
|
+
|
41
|
+
normalizer = PgSearch::Normalizer.new(config)
|
42
|
+
expect {
|
43
|
+
normalizer.add_normalization("foo")
|
44
|
+
}.to raise_exception(PgSearch::NotSupportedForPostgresqlVersion)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "when config[:ignore] does not include :accents" do
|
49
|
+
it "passes the expression through" do
|
50
|
+
config = stub("config", :ignore => [], :postgresql_version => 90000)
|
51
|
+
|
52
|
+
normalizer = PgSearch::Normalizer.new(config)
|
53
|
+
normalizer.add_normalization("foo").should == "foo"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/spec/pg_search_spec.rb
CHANGED
@@ -751,6 +751,50 @@ describe "an ActiveRecord model which includes PgSearch" do
|
|
751
751
|
end
|
752
752
|
end
|
753
753
|
end
|
754
|
+
|
755
|
+
context "on an STI subclass" do
|
756
|
+
with_model :SuperclassModel do
|
757
|
+
table do |t|
|
758
|
+
t.text 'content'
|
759
|
+
t.string 'type'
|
760
|
+
end
|
761
|
+
|
762
|
+
model do
|
763
|
+
include PgSearch
|
764
|
+
end
|
765
|
+
end
|
766
|
+
|
767
|
+
before do
|
768
|
+
SuperclassModel.pg_search_scope :search_content, :against => :content
|
769
|
+
|
770
|
+
class SubclassModel < SuperclassModel
|
771
|
+
end
|
772
|
+
|
773
|
+
class AnotherSubclassModel < SuperclassModel
|
774
|
+
end
|
775
|
+
end
|
776
|
+
|
777
|
+
it "should returns only results for that subclass" do
|
778
|
+
included = [
|
779
|
+
SubclassModel.create!(:content => "foo bar")
|
780
|
+
]
|
781
|
+
excluded = [
|
782
|
+
SubclassModel.create!(:content => "baz"),
|
783
|
+
SuperclassModel.create!(:content => "foo bar"),
|
784
|
+
SuperclassModel.create!(:content => "baz"),
|
785
|
+
AnotherSubclassModel.create!(:content => "foo bar"),
|
786
|
+
AnotherSubclassModel.create!(:content => "baz")
|
787
|
+
]
|
788
|
+
|
789
|
+
SuperclassModel.count.should == 6
|
790
|
+
SubclassModel.count.should == 2
|
791
|
+
|
792
|
+
results = SubclassModel.search_content("foo bar")
|
793
|
+
|
794
|
+
results.should include(*included)
|
795
|
+
results.should_not include(*excluded)
|
796
|
+
end
|
797
|
+
end
|
754
798
|
end
|
755
799
|
|
756
800
|
describe ".multisearchable" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pg_search
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-09-
|
12
|
+
date: 2012-09-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -83,7 +83,6 @@ files:
|
|
83
83
|
- lib/pg_search/multisearchable.rb
|
84
84
|
- lib/pg_search/normalizer.rb
|
85
85
|
- lib/pg_search/railtie.rb
|
86
|
-
- lib/pg_search/scope.rb
|
87
86
|
- lib/pg_search/scope_options.rb
|
88
87
|
- lib/pg_search/tasks.rb
|
89
88
|
- lib/pg_search/version.rb
|
@@ -92,6 +91,7 @@ files:
|
|
92
91
|
- spec/pg_search/document_spec.rb
|
93
92
|
- spec/pg_search/multisearch_spec.rb
|
94
93
|
- spec/pg_search/multisearchable_spec.rb
|
94
|
+
- spec/pg_search/normalizer_spec.rb
|
95
95
|
- spec/pg_search_spec.rb
|
96
96
|
- spec/spec_helper.rb
|
97
97
|
- sql/array_agg.sql
|
@@ -114,7 +114,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
114
114
|
version: '0'
|
115
115
|
segments:
|
116
116
|
- 0
|
117
|
-
hash:
|
117
|
+
hash: -4514756727807360588
|
118
118
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
119
|
none: false
|
120
120
|
requirements:
|
@@ -123,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
123
|
version: '0'
|
124
124
|
segments:
|
125
125
|
- 0
|
126
|
-
hash:
|
126
|
+
hash: -4514756727807360588
|
127
127
|
requirements: []
|
128
128
|
rubyforge_project:
|
129
129
|
rubygems_version: 1.8.24
|
@@ -136,5 +136,6 @@ test_files:
|
|
136
136
|
- spec/pg_search/document_spec.rb
|
137
137
|
- spec/pg_search/multisearch_spec.rb
|
138
138
|
- spec/pg_search/multisearchable_spec.rb
|
139
|
+
- spec/pg_search/normalizer_spec.rb
|
139
140
|
- spec/pg_search_spec.rb
|
140
141
|
- spec/spec_helper.rb
|
data/lib/pg_search/scope.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
module PgSearch
|
2
|
-
class Scope
|
3
|
-
def initialize(name, model, scope_options_or_proc)
|
4
|
-
@name = name
|
5
|
-
@model = model
|
6
|
-
@options_proc = build_options_proc(scope_options_or_proc)
|
7
|
-
end
|
8
|
-
|
9
|
-
def build_relation(*args)
|
10
|
-
config = Configuration.new(@options_proc.call(*args), @model)
|
11
|
-
scope_options = ScopeOptions.new(@name, config)
|
12
|
-
scope_options.apply(@model)
|
13
|
-
end
|
14
|
-
|
15
|
-
private
|
16
|
-
|
17
|
-
def build_options_proc(scope_options)
|
18
|
-
return scope_options if scope_options.respond_to?(:call)
|
19
|
-
|
20
|
-
unless scope_options.respond_to?(:merge)
|
21
|
-
raise ArgumentError, "pg_search_scope expects a Hash or Proc"
|
22
|
-
end
|
23
|
-
|
24
|
-
lambda { |query| {:query => query}.merge(scope_options) }
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|