pg_search 1.0.4 → 1.0.5
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.
- checksums.yaml +4 -4
- data/.codeclimate.yml +2 -0
- data/.rubocop.yml +21 -0
- data/.rubocop_todo.yml +0 -153
- data/.travis.yml +7 -1
- data/CHANGELOG.md +5 -0
- data/Gemfile +5 -3
- data/README.md +23 -5
- data/lib/pg_search.rb +3 -9
- data/lib/pg_search/configuration.rb +0 -1
- data/lib/pg_search/document.rb +1 -1
- data/lib/pg_search/extensions/arel.rb +1 -1
- data/lib/pg_search/features/tsearch.rb +2 -2
- data/lib/pg_search/multisearch.rb +0 -1
- data/lib/pg_search/multisearch/rebuilder.rb +2 -4
- data/lib/pg_search/multisearchable.rb +3 -3
- data/lib/pg_search/normalizer.rb +1 -1
- data/lib/pg_search/scope_options.rb +52 -31
- data/lib/pg_search/tasks.rb +1 -1
- data/lib/pg_search/version.rb +1 -1
- data/pg_search.gemspec +3 -3
- data/spec/.rubocop.yml +14 -0
- data/spec/integration/associations_spec.rb +50 -40
- data/spec/integration/pg_search_spec.rb +42 -32
- data/spec/lib/pg_search/configuration/column_spec.rb +2 -2
- data/spec/lib/pg_search/configuration/foreign_column_spec.rb +2 -2
- data/spec/lib/pg_search/features/dmetaphone_spec.rb +2 -2
- data/spec/lib/pg_search/features/trigram_spec.rb +6 -6
- data/spec/lib/pg_search/features/tsearch_spec.rb +6 -6
- data/spec/lib/pg_search/multisearch/rebuilder_spec.rb +6 -6
- data/spec/lib/pg_search/multisearchable_spec.rb +2 -3
- data/spec/lib/pg_search_spec.rb +20 -30
- data/spec/spec_helper.rb +5 -0
- data/spec/support/database.rb +4 -4
- metadata +8 -6
@@ -2,7 +2,7 @@ require "active_support/core_ext/class/attribute"
|
|
2
2
|
|
3
3
|
module PgSearch
|
4
4
|
module Multisearchable
|
5
|
-
def self.included
|
5
|
+
def self.included(mod)
|
6
6
|
mod.class_eval do
|
7
7
|
has_one :pg_search_document,
|
8
8
|
:as => :searchable,
|
@@ -10,11 +10,11 @@ module PgSearch
|
|
10
10
|
:dependent => :delete
|
11
11
|
|
12
12
|
after_save :update_pg_search_document,
|
13
|
-
:if =>
|
13
|
+
:if => -> { PgSearch.multisearch_enabled? }
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
def update_pg_search_document
|
17
|
+
def update_pg_search_document # rubocop:disable Metrics/AbcSize
|
18
18
|
if_conditions = Array(pg_search_multisearchable_options[:if])
|
19
19
|
unless_conditions = Array(pg_search_multisearchable_options[:unless])
|
20
20
|
|
data/lib/pg_search/normalizer.rb
CHANGED
@@ -13,22 +13,12 @@ module PgSearch
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def apply(scope)
|
16
|
-
|
17
|
-
|
18
|
-
scope.scoped
|
19
|
-
else
|
20
|
-
scope.all.spawn
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
alias_id = scope.instance_variable_get(:@pg_search_scope_applied_count) || 0
|
25
|
-
scope.instance_variable_set(:@pg_search_scope_applied_count, alias_id + 1)
|
26
|
-
|
27
|
-
aka = pg_search_alias scope, alias_id
|
16
|
+
scope = include_table_aliasing_for_rank(scope)
|
17
|
+
rank_table_alias = scope.pg_search_rank_table_alias(:include_counter)
|
28
18
|
|
29
19
|
scope
|
30
|
-
.joins(rank_join(
|
31
|
-
.order("#{
|
20
|
+
.joins(rank_join(rank_table_alias))
|
21
|
+
.order("#{rank_table_alias}.rank DESC, #{order_within_rank}")
|
32
22
|
.extend(DisableEagerLoading)
|
33
23
|
.extend(WithPgSearchRank)
|
34
24
|
end
|
@@ -43,11 +33,33 @@ module PgSearch
|
|
43
33
|
module WithPgSearchRank
|
44
34
|
def with_pg_search_rank
|
45
35
|
scope = self
|
46
|
-
scope = scope.select("
|
47
|
-
|
48
|
-
|
36
|
+
scope = scope.select("#{table_name}.*") unless scope.select_values.any?
|
37
|
+
scope.select("#{pg_search_rank_table_alias}.rank AS pg_search_rank")
|
38
|
+
end
|
39
|
+
end
|
49
40
|
|
50
|
-
|
41
|
+
module PgSearchRankTableAliasing
|
42
|
+
def pg_search_rank_table_alias(include_counter = false)
|
43
|
+
components = [arel_table.name]
|
44
|
+
if include_counter
|
45
|
+
count = pg_search_scope_application_count_plus_plus
|
46
|
+
components << count if count > 0
|
47
|
+
end
|
48
|
+
|
49
|
+
Configuration.alias(components)
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
attr_writer :pg_search_scope_application_count
|
55
|
+
def pg_search_scope_application_count
|
56
|
+
@pg_search_scope_application_count ||= 0
|
57
|
+
end
|
58
|
+
|
59
|
+
def pg_search_scope_application_count_plus_plus
|
60
|
+
count = pg_search_scope_application_count
|
61
|
+
self.pg_search_scope_application_count = pg_search_scope_application_count + 1
|
62
|
+
count
|
51
63
|
end
|
52
64
|
end
|
53
65
|
|
@@ -67,13 +79,19 @@ module PgSearch
|
|
67
79
|
end
|
68
80
|
|
69
81
|
def conditions
|
70
|
-
config.features.reject do |
|
82
|
+
conditions = config.features.reject do |_feature_name, feature_options|
|
71
83
|
feature_options && feature_options[:sort_only]
|
72
|
-
end
|
84
|
+
end
|
85
|
+
|
86
|
+
conditions.map! do |feature_name, _feature_options|
|
73
87
|
feature_for(feature_name).conditions
|
74
|
-
end
|
88
|
+
end
|
89
|
+
|
90
|
+
conditions = conditions.inject do |accumulator, expression|
|
75
91
|
Arel::Nodes::Or.new(accumulator, expression)
|
76
|
-
end
|
92
|
+
end
|
93
|
+
|
94
|
+
conditions.to_sql
|
77
95
|
end
|
78
96
|
|
79
97
|
def order_within_rank
|
@@ -85,7 +103,7 @@ module PgSearch
|
|
85
103
|
end
|
86
104
|
|
87
105
|
def subquery_join
|
88
|
-
if config.associations.any?
|
106
|
+
if config.associations.any? # rubocop:disable Style/GuardClause
|
89
107
|
config.associations.map do |association|
|
90
108
|
association.join(primary_key)
|
91
109
|
end.join(' ')
|
@@ -98,7 +116,7 @@ module PgSearch
|
|
98
116
|
:trigram => Features::Trigram
|
99
117
|
}
|
100
118
|
|
101
|
-
def feature_for(feature_name)
|
119
|
+
def feature_for(feature_name) # rubocop:disable Metrics/AbcSize
|
102
120
|
feature_name = feature_name.to_sym
|
103
121
|
feature_class = FEATURE_CLASSES[feature_name]
|
104
122
|
|
@@ -121,15 +139,18 @@ module PgSearch
|
|
121
139
|
end
|
122
140
|
end
|
123
141
|
|
124
|
-
def
|
125
|
-
|
126
|
-
prefix = "pg_search_#{arel_table.name}"
|
127
|
-
|
128
|
-
0 == n ? prefix : "#{prefix}_#{n}"
|
142
|
+
def rank_join(rank_table_alias)
|
143
|
+
"INNER JOIN (#{subquery.to_sql}) AS #{rank_table_alias} ON #{primary_key} = #{rank_table_alias}.pg_search_id"
|
129
144
|
end
|
130
145
|
|
131
|
-
def
|
132
|
-
|
146
|
+
def include_table_aliasing_for_rank(scope)
|
147
|
+
if scope.included_modules.include?(PgSearchRankTableAliasing)
|
148
|
+
scope
|
149
|
+
else
|
150
|
+
(::ActiveRecord::VERSION::MAJOR < 4 ? scope.scoped : scope.all.spawn).tap do |new_scope|
|
151
|
+
new_scope.class_eval { include PgSearchRankTableAliasing }
|
152
|
+
end
|
153
|
+
end
|
133
154
|
end
|
134
155
|
end
|
135
156
|
end
|
data/lib/pg_search/tasks.rb
CHANGED
@@ -4,7 +4,7 @@ require 'pg_search'
|
|
4
4
|
namespace :pg_search do
|
5
5
|
namespace :multisearch do
|
6
6
|
desc "Rebuild PgSearch multisearch records for a given model"
|
7
|
-
task :rebuild, [:model,:schema] => :environment do |
|
7
|
+
task :rebuild, [:model,:schema] => :environment do |_task, args|
|
8
8
|
raise ArgumentError, <<-MESSAGE.strip_heredoc unless args.model
|
9
9
|
You must pass a model as an argument.
|
10
10
|
Example: rake pg_search:multisearch:rebuild[BlogPost]
|
data/lib/pg_search/version.rb
CHANGED
data/pg_search.gemspec
CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.authors = ["Grant Hutchins", "Case Commons, LLC"]
|
10
10
|
s.email = ["gems@nertzy.com", "casecommons-dev@googlegroups.com"]
|
11
11
|
s.homepage = "https://github.com/Casecommons/pg_search"
|
12
|
-
s.summary = %q
|
13
|
-
s.description = %q
|
12
|
+
s.summary = %q(PgSearch builds Active Record named scopes that take advantage of PostgreSQL's full text search)
|
13
|
+
s.description = %q(PgSearch builds Active Record named scopes that take advantage of PostgreSQL's full text search)
|
14
14
|
s.licenses = ["MIT"]
|
15
15
|
|
16
16
|
s.files = `git ls-files`.split("\n")
|
@@ -23,7 +23,7 @@ Gem::Specification.new do |s|
|
|
23
23
|
|
24
24
|
s.add_development_dependency 'rake'
|
25
25
|
s.add_development_dependency 'pry'
|
26
|
-
s.add_development_dependency 'rspec', '
|
26
|
+
s.add_development_dependency 'rspec', '>= 3.3'
|
27
27
|
s.add_development_dependency 'with_model', '>= 1.2'
|
28
28
|
s.add_development_dependency 'rubocop', '>= 0.30.0'
|
29
29
|
|
data/spec/.rubocop.yml
ADDED
@@ -67,7 +67,7 @@ describe PgSearch do
|
|
67
67
|
ModelWithBelongsTo.create!(:title => 'abcdef')
|
68
68
|
]
|
69
69
|
excluded = ModelWithBelongsTo.create!(:title => 'mnopqr',
|
70
|
-
|
70
|
+
:another_model => AssociatedModel.create!(:title => 'stuvwx'))
|
71
71
|
|
72
72
|
results = ModelWithBelongsTo.with_associated('abcdef')
|
73
73
|
expect(results.map(&:title)).to match_array(included.map(&:title))
|
@@ -99,17 +99,17 @@ describe PgSearch do
|
|
99
99
|
it "returns rows that match the query in either its own columns or the columns of the associated model" do
|
100
100
|
included = [
|
101
101
|
ModelWithHasMany.create!(:title => 'abcdef', :other_models => [
|
102
|
-
|
103
|
-
|
104
|
-
|
102
|
+
AssociatedModelWithHasMany.create!(:title => 'foo'),
|
103
|
+
AssociatedModelWithHasMany.create!(:title => 'bar')
|
104
|
+
]),
|
105
105
|
ModelWithHasMany.create!(:title => 'ghijkl', :other_models => [
|
106
|
-
|
107
|
-
|
108
|
-
|
106
|
+
AssociatedModelWithHasMany.create!(:title => 'foo bar'),
|
107
|
+
AssociatedModelWithHasMany.create!(:title => 'mnopqr')
|
108
|
+
]),
|
109
109
|
ModelWithHasMany.create!(:title => 'foo bar')
|
110
110
|
]
|
111
111
|
excluded = ModelWithHasMany.create!(:title => 'stuvwx', :other_models => [
|
112
|
-
|
112
|
+
AssociatedModelWithHasMany.create!(:title => 'abcdef')
|
113
113
|
])
|
114
114
|
|
115
115
|
results = ModelWithHasMany.with_associated('foo bar')
|
@@ -137,7 +137,6 @@ describe PgSearch do
|
|
137
137
|
expect(results.map(&:title)).to match_array(included.map(&:title))
|
138
138
|
expect(results).not_to include(excluded)
|
139
139
|
end
|
140
|
-
|
141
140
|
end
|
142
141
|
|
143
142
|
context "across multiple associations" do
|
@@ -165,10 +164,16 @@ describe PgSearch do
|
|
165
164
|
|
166
165
|
model do
|
167
166
|
include PgSearch
|
168
|
-
has_many :models_of_first_type, :class_name => 'FirstAssociatedModel', :foreign_key => 'ModelWithManyAssociations_id'
|
169
|
-
belongs_to :model_of_second_type, :class_name => 'SecondAssociatedModel'
|
170
167
|
|
171
|
-
|
168
|
+
has_many :models_of_first_type,
|
169
|
+
:class_name => 'FirstAssociatedModel',
|
170
|
+
:foreign_key => 'ModelWithManyAssociations_id'
|
171
|
+
|
172
|
+
belongs_to :model_of_second_type,
|
173
|
+
:class_name => 'SecondAssociatedModel'
|
174
|
+
|
175
|
+
pg_search_scope :with_associated,
|
176
|
+
:against => :title,
|
172
177
|
:associated_against => {:models_of_first_type => :title, :model_of_second_type => :title}
|
173
178
|
end
|
174
179
|
end
|
@@ -179,20 +184,20 @@ describe PgSearch do
|
|
179
184
|
|
180
185
|
included = [
|
181
186
|
ModelWithManyAssociations.create!(:title => 'abcdef', :models_of_first_type => [
|
182
|
-
|
183
|
-
|
184
|
-
|
187
|
+
FirstAssociatedModel.create!(:title => 'foo'),
|
188
|
+
FirstAssociatedModel.create!(:title => 'bar')
|
189
|
+
]),
|
185
190
|
ModelWithManyAssociations.create!(:title => 'ghijkl', :models_of_first_type => [
|
186
|
-
|
187
|
-
|
188
|
-
|
191
|
+
FirstAssociatedModel.create!(:title => 'foo bar'),
|
192
|
+
FirstAssociatedModel.create!(:title => 'mnopqr')
|
193
|
+
]),
|
189
194
|
ModelWithManyAssociations.create!(:title => 'foo bar'),
|
190
195
|
ModelWithManyAssociations.create!(:title => 'qwerty', :model_of_second_type => matching_second)
|
191
196
|
]
|
192
197
|
excluded = [
|
193
198
|
ModelWithManyAssociations.create!(:title => 'stuvwx', :models_of_first_type => [
|
194
|
-
|
195
|
-
|
199
|
+
FirstAssociatedModel.create!(:title => 'abcdef')
|
200
|
+
]),
|
196
201
|
ModelWithManyAssociations.create!(:title => 'qwerty', :model_of_second_type => unmatching_second)
|
197
202
|
]
|
198
203
|
|
@@ -219,36 +224,42 @@ describe PgSearch do
|
|
219
224
|
|
220
225
|
model do
|
221
226
|
include PgSearch
|
222
|
-
|
223
|
-
has_many :
|
227
|
+
|
228
|
+
has_many :things,
|
229
|
+
:class_name => 'DoublyAssociatedModel',
|
230
|
+
:foreign_key => 'ModelWithDoubleAssociation_id'
|
231
|
+
|
232
|
+
has_many :thingamabobs,
|
233
|
+
:class_name => 'DoublyAssociatedModel',
|
234
|
+
:foreign_key => 'ModelWithDoubleAssociation_again_id'
|
224
235
|
|
225
236
|
pg_search_scope :with_associated, :against => :title,
|
226
|
-
|
237
|
+
:associated_against => {:things => :title, :thingamabobs => :title}
|
227
238
|
end
|
228
239
|
end
|
229
240
|
|
230
241
|
it "returns rows that match the query in either its own columns or the columns of the associated model" do
|
231
242
|
included = [
|
232
243
|
ModelWithDoubleAssociation.create!(:title => 'abcdef', :things => [
|
233
|
-
|
234
|
-
|
235
|
-
|
244
|
+
DoublyAssociatedModel.create!(:title => 'foo'),
|
245
|
+
DoublyAssociatedModel.create!(:title => 'bar')
|
246
|
+
]),
|
236
247
|
ModelWithDoubleAssociation.create!(:title => 'ghijkl', :things => [
|
237
|
-
|
238
|
-
|
239
|
-
|
248
|
+
DoublyAssociatedModel.create!(:title => 'foo bar'),
|
249
|
+
DoublyAssociatedModel.create!(:title => 'mnopqr')
|
250
|
+
]),
|
240
251
|
ModelWithDoubleAssociation.create!(:title => 'foo bar'),
|
241
252
|
ModelWithDoubleAssociation.create!(:title => 'qwerty', :thingamabobs => [
|
242
|
-
|
243
|
-
|
253
|
+
DoublyAssociatedModel.create!(:title => "foo bar")
|
254
|
+
])
|
244
255
|
]
|
245
256
|
excluded = [
|
246
257
|
ModelWithDoubleAssociation.create!(:title => 'stuvwx', :things => [
|
247
|
-
|
248
|
-
|
258
|
+
DoublyAssociatedModel.create!(:title => 'abcdef')
|
259
|
+
]),
|
249
260
|
ModelWithDoubleAssociation.create!(:title => 'qwerty', :thingamabobs => [
|
250
|
-
|
251
|
-
|
261
|
+
DoublyAssociatedModel.create!(:title => "uiop")
|
262
|
+
])
|
252
263
|
]
|
253
264
|
|
254
265
|
results = ModelWithDoubleAssociation.with_associated('foo bar')
|
@@ -309,7 +320,6 @@ describe PgSearch do
|
|
309
320
|
included.each { |object| expect(results).to include(object) }
|
310
321
|
excluded.each { |object| expect(results).not_to include(object) }
|
311
322
|
end
|
312
|
-
|
313
323
|
end
|
314
324
|
|
315
325
|
context "against non-text columns" do
|
@@ -414,13 +424,13 @@ describe PgSearch do
|
|
414
424
|
excluded_associated_2 = AssociatedModel.create(:content => "baz bar")
|
415
425
|
|
416
426
|
included = [
|
417
|
-
|
418
|
-
|
427
|
+
ModelWithAssociation.create(:associated_models => [included_associated_1]),
|
428
|
+
ModelWithAssociation.create(:associated_models => [included_associated_2, excluded_associated_1])
|
419
429
|
]
|
420
430
|
|
421
431
|
excluded = [
|
422
|
-
|
423
|
-
|
432
|
+
ModelWithAssociation.create(:associated_models => [excluded_associated_2]),
|
433
|
+
ModelWithAssociation.create(:associated_models => [])
|
424
434
|
]
|
425
435
|
|
426
436
|
relation = AssociatedModel.search_content("foo")
|
@@ -5,11 +5,24 @@ describe "an Active Record model which includes PgSearch" do
|
|
5
5
|
table do |t|
|
6
6
|
t.string 'title'
|
7
7
|
t.text 'content'
|
8
|
+
t.integer 'parent_model_id'
|
8
9
|
t.integer 'importance'
|
9
10
|
end
|
10
11
|
|
11
12
|
model do
|
12
13
|
include PgSearch
|
14
|
+
belongs_to :parent_model
|
15
|
+
end
|
16
|
+
end
|
17
|
+
with_model :ParentModel do
|
18
|
+
table do |t|
|
19
|
+
t.boolean :active, default: true
|
20
|
+
end
|
21
|
+
|
22
|
+
model do
|
23
|
+
include PgSearch
|
24
|
+
has_many :models_with_pg_search
|
25
|
+
scope :active, -> { where(active: true) }
|
13
26
|
end
|
14
27
|
end
|
15
28
|
|
@@ -52,7 +65,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
52
65
|
context "dynamically" do
|
53
66
|
it "raises an exception when invoked" do
|
54
67
|
ModelWithPgSearch.pg_search_scope :with_unknown_option,
|
55
|
-
|
68
|
+
->(*) { {:against => :content, :foo => :bar} }
|
56
69
|
|
57
70
|
expect {
|
58
71
|
ModelWithPgSearch.with_unknown_option("foo")
|
@@ -75,7 +88,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
75
88
|
context "dynamically" do
|
76
89
|
it "raises an exception when invoked" do
|
77
90
|
ModelWithPgSearch.pg_search_scope :with_unknown_using,
|
78
|
-
|
91
|
+
->(*) { {:against => :content, :using => :foo} }
|
79
92
|
|
80
93
|
expect {
|
81
94
|
ModelWithPgSearch.with_unknown_using("foo")
|
@@ -98,7 +111,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
98
111
|
context "dynamically" do
|
99
112
|
it "raises an exception when invoked" do
|
100
113
|
ModelWithPgSearch.pg_search_scope :with_unknown_ignoring,
|
101
|
-
|
114
|
+
->(*) { {:against => :content, :ignoring => :foo} }
|
102
115
|
|
103
116
|
expect {
|
104
117
|
ModelWithPgSearch.with_unknown_ignoring("foo")
|
@@ -117,8 +130,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
117
130
|
|
118
131
|
context "dynamically" do
|
119
132
|
it "raises an exception when invoked" do
|
120
|
-
ModelWithPgSearch.pg_search_scope :with_unknown_ignoring,
|
121
|
-
lambda { |*| {} }
|
133
|
+
ModelWithPgSearch.pg_search_scope :with_unknown_ignoring, ->(*){ {} }
|
122
134
|
|
123
135
|
expect {
|
124
136
|
ModelWithPgSearch.with_unknown_ignoring("foo")
|
@@ -209,10 +221,10 @@ describe "an Active Record model which includes PgSearch" do
|
|
209
221
|
include PgSearch
|
210
222
|
has_many :houses
|
211
223
|
pg_search_scope :named, against: [:name]
|
212
|
-
scope :with_house_in_city,
|
224
|
+
scope :with_house_in_city, lambda { |city|
|
213
225
|
joins(:houses).where(House.table_name.to_sym => {city: city})
|
214
226
|
}
|
215
|
-
scope :house_search_city,
|
227
|
+
scope :house_search_city, lambda { |query|
|
216
228
|
joins(:houses).merge(House.search_city(query))
|
217
229
|
}
|
218
230
|
end
|
@@ -314,7 +326,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
314
326
|
|
315
327
|
returned_record = records_with_only_id.first
|
316
328
|
|
317
|
-
expect(returned_record.attributes).to eq(
|
329
|
+
expect(returned_record.attributes).to eq("id" => record.id)
|
318
330
|
end
|
319
331
|
|
320
332
|
unless ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR < 2
|
@@ -332,7 +344,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
332
344
|
twice = ModelWithPgSearch.create!(:content => 'foo foo')
|
333
345
|
|
334
346
|
records = ModelWithPgSearch.search_content('foo')
|
335
|
-
.where("
|
347
|
+
.where("#{PgSearch::Configuration.alias(ModelWithPgSearch.table_name)}.rank > 0.07")
|
336
348
|
|
337
349
|
expect(records).to eq [twice]
|
338
350
|
end
|
@@ -394,6 +406,18 @@ describe "an Active Record model which includes PgSearch" do
|
|
394
406
|
expect(results).to eq([winner, loser])
|
395
407
|
end
|
396
408
|
|
409
|
+
it 'allows pg_search_rank along with a join' do
|
410
|
+
parent1 = ParentModel.create!(id: 98)
|
411
|
+
parent2 = ParentModel.create!(id: 99)
|
412
|
+
loser = ModelWithPgSearch.create!(:content => 'foo', parent_model: parent2)
|
413
|
+
winner = ModelWithPgSearch.create!(:content => 'foo foo', parent_model: parent1)
|
414
|
+
|
415
|
+
results = ModelWithPgSearch.joins(:parent_model).merge(ParentModel.active).search_content("foo").with_pg_search_rank
|
416
|
+
expect(results.map(&:id)).to eq [winner.id, loser.id]
|
417
|
+
expect(results[0].pg_search_rank).to be > results[1].pg_search_rank
|
418
|
+
expect(results).to eq([winner, loser])
|
419
|
+
end
|
420
|
+
|
397
421
|
it "returns results that match sorted by primary key for records that rank the same" do
|
398
422
|
sorted_results = [ModelWithPgSearch.create!(:content => 'foo'),
|
399
423
|
ModelWithPgSearch.create!(:content => 'foo')].sort_by(&:id)
|
@@ -484,7 +508,7 @@ describe "an Active Record model which includes PgSearch" do
|
|
484
508
|
in_title = ModelWithPgSearch.create!(:title => 'foo', :content => 'bar')
|
485
509
|
in_content = ModelWithPgSearch.create!(:title => 'bar', :content => 'foo')
|
486
510
|
|
487
|
-
results
|
511
|
+
results = ModelWithPgSearch.search_title_and_content('foo')
|
488
512
|
expect(results).to match_array([in_title, in_content])
|
489
513
|
end
|
490
514
|
|
@@ -541,10 +565,10 @@ describe "an Active Record model which includes PgSearch" do
|
|
541
565
|
context "using tsearch" do
|
542
566
|
before do
|
543
567
|
ModelWithPgSearch.pg_search_scope :search_title_with_prefixes,
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
568
|
+
:against => :title,
|
569
|
+
:using => {
|
570
|
+
:tsearch => {:prefix => true}
|
571
|
+
}
|
548
572
|
end
|
549
573
|
|
550
574
|
if ActiveRecord::Base.connection.send(:postgresql_version) < 80400
|
@@ -698,16 +722,16 @@ describe "an Active Record model which includes PgSearch" do
|
|
698
722
|
:tsearch => {:any_word => true}
|
699
723
|
}
|
700
724
|
|
701
|
-
|
702
|
-
|
725
|
+
ModelWithPgSearch.pg_search_scope :search_title_with_all_words,
|
726
|
+
:against => :title
|
703
727
|
end
|
704
728
|
|
705
729
|
it "returns all results containing any word in their title" do
|
706
|
-
numbers = %w
|
730
|
+
numbers = %w[one two three four].map{|number| ModelWithPgSearch.create!(:title => number)}
|
707
731
|
|
708
732
|
results = ModelWithPgSearch.search_title_with_any_word("one two three four")
|
709
733
|
|
710
|
-
expect(results.map(&:title)).to eq(%w
|
734
|
+
expect(results.map(&:title)).to eq(%w[one two three four])
|
711
735
|
|
712
736
|
results = ModelWithPgSearch.search_title_with_all_words("one two three four")
|
713
737
|
|
@@ -1167,7 +1191,6 @@ describe "an Active Record model which includes PgSearch" do
|
|
1167
1191
|
:against => :content,
|
1168
1192
|
:ranked_by => ":tsearch"
|
1169
1193
|
|
1170
|
-
|
1171
1194
|
once = ModelWithPgSearch.create!(:content => 'foo bar')
|
1172
1195
|
twice = ModelWithPgSearch.create!(:content => 'foo foo')
|
1173
1196
|
|
@@ -1227,17 +1250,4 @@ describe "an Active Record model which includes PgSearch" do
|
|
1227
1250
|
end
|
1228
1251
|
end
|
1229
1252
|
end
|
1230
|
-
|
1231
|
-
describe ".multisearchable" do
|
1232
|
-
it "should include the Multisearchable module" do
|
1233
|
-
expect(ModelWithPgSearch).to receive(:include).with(PgSearch::Multisearchable)
|
1234
|
-
ModelWithPgSearch.multisearchable
|
1235
|
-
end
|
1236
|
-
|
1237
|
-
it "should set pg_search_multisearchable_options on the class" do
|
1238
|
-
options = double(:options)
|
1239
|
-
ModelWithPgSearch.multisearchable(options)
|
1240
|
-
expect(ModelWithPgSearch.pg_search_multisearchable_options).to eq(options)
|
1241
|
-
end
|
1242
|
-
end
|
1243
1253
|
end
|