pg_search 2.3.7 → 2.4.0

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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +38 -37
  3. data/.github/workflows/codeql.yml +86 -0
  4. data/.gitignore +0 -1
  5. data/.standard.yml +2 -2
  6. data/CHANGELOG.md +81 -64
  7. data/CONTRIBUTING.md +1 -1
  8. data/Gemfile +4 -2
  9. data/LICENSE +1 -1
  10. data/README.md +89 -87
  11. data/Rakefile +1 -7
  12. data/doc/plans/2026-09-05-arel-stack.md +43 -0
  13. data/doc/plans/2026-09-06-arel-remaining-expressions.md +48 -0
  14. data/lib/pg_search/configuration/association.rb +37 -23
  15. data/lib/pg_search/configuration/column.rb +17 -12
  16. data/lib/pg_search/configuration/foreign_column.rb +3 -5
  17. data/lib/pg_search/configuration.rb +10 -26
  18. data/lib/pg_search/features/dmetaphone.rb +3 -7
  19. data/lib/pg_search/features/feature.rb +8 -4
  20. data/lib/pg_search/features/trigram.rb +6 -20
  21. data/lib/pg_search/features/tsearch.rb +47 -61
  22. data/lib/pg_search/features.rb +2 -0
  23. data/lib/pg_search/migration/generator.rb +1 -5
  24. data/lib/pg_search/model.rb +6 -8
  25. data/lib/pg_search/multisearch/rebuilder.rb +69 -64
  26. data/lib/pg_search/normalizer.rb +40 -11
  27. data/lib/pg_search/scope_options.rb +32 -49
  28. data/lib/pg_search/version.rb +1 -1
  29. data/pg_search.gemspec +5 -5
  30. data/spec/integration/associations_spec.rb +133 -0
  31. data/spec/integration/deprecation_spec.rb +5 -1
  32. data/spec/integration/pagination_spec.rb +1 -0
  33. data/spec/integration/pg_search_spec.rb +78 -1
  34. data/spec/integration/single_table_inheritance_spec.rb +2 -0
  35. data/spec/lib/pg_search/configuration/association_spec.rb +34 -58
  36. data/spec/lib/pg_search/configuration/column_spec.rb +73 -15
  37. data/spec/lib/pg_search/configuration/foreign_column_spec.rb +53 -20
  38. data/spec/lib/pg_search/features/dmetaphone_spec.rb +2 -2
  39. data/spec/lib/pg_search/features/trigram_spec.rb +8 -9
  40. data/spec/lib/pg_search/features/tsearch_spec.rb +8 -8
  41. data/spec/lib/pg_search/multisearch/rebuilder_spec.rb +251 -211
  42. data/spec/lib/pg_search/multisearch_spec.rb +16 -16
  43. data/spec/lib/pg_search/multisearchable_spec.rb +8 -0
  44. data/spec/lib/pg_search/normalizer_spec.rb +64 -11
  45. data/spec/lib/pg_search_spec.rb +6 -21
  46. data/spec/spec_helper.rb +0 -13
  47. metadata +11 -15
  48. data/spec/.rubocop.yml +0 -27
  49. data/spec/integration/.rubocop.yml +0 -11
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/module/delegation"
4
-
5
3
  module PgSearch
6
4
  class ScopeOptions
7
5
  attr_reader :config, :feature_options, :model
@@ -15,10 +13,12 @@ module PgSearch
15
13
  def apply(scope)
16
14
  scope = include_table_aliasing_for_rank(scope)
17
15
  rank_table_alias = scope.pg_search_rank_table_alias(include_counter: true)
16
+ rank_subquery = subquery.arel.as(rank_table_alias)
18
17
 
19
18
  scope
20
- .joins(rank_join(rank_table_alias))
21
- .order(Arel.sql("#{rank_table_alias}.rank DESC, #{order_within_rank}"))
19
+ .joins(rank_join(rank_subquery))
20
+ .order(rank_subquery[:rank].desc)
21
+ .order(order_within_rank)
22
22
  .extend(WithPgSearchRank)
23
23
  .extend(WithPgSearchHighlight[feature_for(:tsearch)])
24
24
  end
@@ -27,6 +27,7 @@ module PgSearch
27
27
  def self.[](tsearch)
28
28
  Module.new do
29
29
  include WithPgSearchHighlight
30
+
30
31
  define_method(:tsearch) { tsearch }
31
32
  end
32
33
  end
@@ -37,20 +38,18 @@ module PgSearch
37
38
 
38
39
  def with_pg_search_highlight
39
40
  scope = self
40
- scope = scope.select("#{table_name}.*") unless scope.select_values.any?
41
- scope.select("(#{highlight}) AS pg_search_highlight")
42
- end
43
-
44
- def highlight
45
- tsearch.highlight.to_sql
41
+ scope = scope.select(arel_table[Arel.star]) if scope.select_values.empty?
42
+ scope.select(tsearch.highlight.as("pg_search_highlight"))
46
43
  end
47
44
  end
48
45
 
49
46
  module WithPgSearchRank
50
47
  def with_pg_search_rank
51
48
  scope = self
52
- scope = scope.select("#{table_name}.*") unless scope.select_values.any?
53
- scope.select("#{pg_search_rank_table_alias}.rank AS pg_search_rank")
49
+ scope = scope.select(arel_table[Arel.star]) if scope.select_values.empty?
50
+ rank_table = arel_table.alias(pg_search_rank_table_alias)
51
+ rank_column = Arel::Attributes::Attribute.new(rank_table, "rank")
52
+ scope.select(rank_column.as("pg_search_rank"))
54
53
  end
55
54
  end
56
55
 
@@ -76,13 +75,11 @@ module PgSearch
76
75
 
77
76
  private
78
77
 
79
- delegate :connection, :quoted_table_name, to: :model
80
-
81
78
  def subquery
82
79
  model
83
80
  .unscoped
84
- .select("#{primary_key} AS pg_search_id")
85
- .select("#{rank} AS rank")
81
+ .select(model.arel_table[model.primary_key].as("pg_search_id"))
82
+ .select(rank.as("rank"))
86
83
  .joins(subquery_join)
87
84
  .where(conditions)
88
85
  .limit(nil)
@@ -95,45 +92,26 @@ module PgSearch
95
92
  .reject { |_feature_name, feature_options| feature_options && feature_options[:sort_only] }
96
93
  .map { |feature_name, _feature_options| feature_for(feature_name).conditions }
97
94
 
98
- or_node(expressions)
95
+ Arel::Nodes::Or.new(expressions)
99
96
  end
100
97
 
101
- # https://github.com/rails/rails/pull/51492
102
- # :nocov:
103
- # standard:disable Lint/DuplicateMethods
104
- or_arity = Arel::Nodes::Or.instance_method(:initialize).arity
105
- case or_arity
106
- when 1
107
- def or_node(expressions)
108
- Arel::Nodes::Or.new(expressions)
109
- end
110
- when 2
111
- def or_node(expressions)
112
- expressions.inject { |accumulator, expression| Arel::Nodes::Or.new(accumulator, expression) }
113
- end
114
- else
115
- raise "Unsupported arity #{or_arity} for Arel::Nodes::Or#initialize"
116
- end
117
- # :nocov:
118
- # standard:enable Lint/DuplicateMethods
119
-
120
98
  def order_within_rank
121
- config.order_within_rank || "#{primary_key} ASC"
99
+ if config.order_within_rank
100
+ Arel.sql(config.order_within_rank)
101
+ else
102
+ model.arel_table[model.primary_key].asc
103
+ end
122
104
  end
123
105
 
124
106
  def primary_key
125
- "#{quoted_table_name}.#{connection.quote_column_name(model.primary_key)}"
107
+ Arel::Attributes::Attribute.new(model.arel_table, model.primary_key)
126
108
  end
127
109
 
128
110
  def subquery_join
129
- if config.associations.any?
130
- config.associations.map do |association|
131
- association.join(primary_key)
132
- end.join(" ")
133
- end
111
+ config.associations.map { |association| association.to_arel(primary_key) }
134
112
  end
135
113
 
136
- FEATURE_CLASSES = {
114
+ FEATURE_CLASSES = { # standard:disable Lint/UselessConstantScoping
137
115
  dmetaphone: Features::DMetaphone,
138
116
  tsearch: Features::TSearch,
139
117
  trigram: Features::Trigram
@@ -157,17 +135,22 @@ module PgSearch
157
135
  end
158
136
 
159
137
  def rank
160
- (config.ranking_sql || ":tsearch").gsub(/:(\w*)/) do
138
+ return feature_for(:tsearch).rank unless config.ranking_sql
139
+
140
+ Arel.sql(config.ranking_sql.gsub(/:(\w*)/) do
161
141
  feature_for(Regexp.last_match(1)).rank.to_sql
162
- end
142
+ end)
163
143
  end
164
144
 
165
- def rank_join(rank_table_alias)
166
- "INNER JOIN (#{subquery.to_sql}) AS #{rank_table_alias} ON #{primary_key} = #{rank_table_alias}.pg_search_id"
145
+ def rank_join(rank_subquery)
146
+ model.arel_table
147
+ .join(rank_subquery)
148
+ .on(model.arel_table[model.primary_key].eq(rank_subquery[:pg_search_id]))
149
+ .join_sources
167
150
  end
168
151
 
169
152
  def include_table_aliasing_for_rank(scope)
170
- return scope if scope.included_modules.include?(PgSearchRankTableAliasing)
153
+ return scope if scope.include?(PgSearchRankTableAliasing)
171
154
 
172
155
  scope.all.spawn.tap do |new_scope|
173
156
  new_scope.instance_eval { extend PgSearchRankTableAliasing }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PgSearch
4
- VERSION = "2.3.7"
4
+ VERSION = "2.4.0"
5
5
  end
data/pg_search.gemspec CHANGED
@@ -7,8 +7,8 @@ Gem::Specification.new do |s|
7
7
  s.name = "pg_search"
8
8
  s.version = PgSearch::VERSION
9
9
  s.platform = Gem::Platform::RUBY
10
- s.authors = ["Grant Hutchins", "Case Commons, LLC"]
11
- s.email = %w[gems@nertzy.com casecommons-dev@googlegroups.com]
10
+ s.authors = ["Grant Hutchins"]
11
+ s.email = ["gems@nertzy.com"]
12
12
  s.homepage = "https://github.com/Casecommons/pg_search"
13
13
  s.summary = "PgSearch builds Active Record named scopes that take advantage of PostgreSQL's full text search"
14
14
  s.description = "PgSearch builds Active Record named scopes that take advantage of PostgreSQL's full text search"
@@ -18,8 +18,8 @@ Gem::Specification.new do |s|
18
18
  s.files = `git ls-files -z`.split("\x0")
19
19
  s.require_paths = ["lib"]
20
20
 
21
- s.add_dependency "activerecord", ">= 6.1"
22
- s.add_dependency "activesupport", ">= 6.1"
21
+ s.add_dependency "activerecord", ">= 8.0"
22
+ s.add_dependency "activesupport", ">= 8.0"
23
23
 
24
- s.required_ruby_version = ">= 3.0"
24
+ s.required_ruby_version = ">= 3.3"
25
25
  end
@@ -20,6 +20,7 @@ describe "a pg_search_scope" do
20
20
 
21
21
  model do
22
22
  include PgSearch::Model
23
+
23
24
  belongs_to :another_model, class_name: "AssociatedModel"
24
25
 
25
26
  pg_search_scope :with_another, associated_against: {another_model: :title}
@@ -57,6 +58,7 @@ describe "a pg_search_scope" do
57
58
 
58
59
  model do
59
60
  include PgSearch::Model
61
+
60
62
  belongs_to :another_model, class_name: "AssociatedModel"
61
63
 
62
64
  pg_search_scope :with_associated, against: :title, associated_against: {another_model: :title}
@@ -93,6 +95,7 @@ describe "a pg_search_scope" do
93
95
 
94
96
  model do
95
97
  include PgSearch::Model
98
+
96
99
  has_many :other_models, class_name: "AssociatedModelWithHasMany", foreign_key: "ModelWithHasMany_id"
97
100
 
98
101
  pg_search_scope :with_associated, against: [:title], associated_against: {other_models: :title}
@@ -142,6 +145,127 @@ describe "a pg_search_scope" do
142
145
  end
143
146
  end
144
147
 
148
+ context "via a scoped has_many association with a quoted literal condition" do
149
+ with_model :Book do
150
+ table do |t|
151
+ t.string "title"
152
+ t.string "author"
153
+ t.belongs_to :shelf
154
+ end
155
+
156
+ model do
157
+ belongs_to :shelf
158
+ end
159
+ end
160
+
161
+ with_model :Shelf do
162
+ table do |t|
163
+ t.string "title"
164
+ end
165
+
166
+ model do
167
+ include PgSearch::Model
168
+
169
+ has_many :obrien_books,
170
+ -> { where(author: "O'Brien") },
171
+ class_name: "Book"
172
+
173
+ pg_search_scope :with_obrien_books,
174
+ associated_against: {obrien_books: :title}
175
+ end
176
+ end
177
+
178
+ it "preserves scoped values through searches" do
179
+ shelf_with_obrien = Shelf.create!(title: "Main Shelf")
180
+ shelf_without_obrien = Shelf.create!(title: "Other Shelf")
181
+
182
+ Book.create!(
183
+ title: "The Third Policeman",
184
+ author: "O'Brien",
185
+ shelf: shelf_with_obrien
186
+ )
187
+ Book.create!(
188
+ title: "The Third Policeman",
189
+ author: "Someone Else",
190
+ shelf: shelf_without_obrien
191
+ )
192
+
193
+ results = Shelf.with_obrien_books("Third Policeman")
194
+ expect(results).to include(shelf_with_obrien)
195
+ expect(results).not_to include(shelf_without_obrien)
196
+ end
197
+ end
198
+
199
+ context "with a physical source column shadowed by a model alias" do
200
+ with_model :Book do
201
+ table do |t|
202
+ t.string :title
203
+ t.string :name
204
+ t.belongs_to :shelf
205
+ end
206
+
207
+ model do
208
+ belongs_to :shelf
209
+ end
210
+ end
211
+
212
+ with_model :Shelf do
213
+ table
214
+
215
+ model do
216
+ include PgSearch::Model
217
+
218
+ has_many :books
219
+
220
+ pg_search_scope :search, associated_against: {books: :title}
221
+ end
222
+ end
223
+
224
+ it "searches the physical association source through the derived alias" do
225
+ shelf = Shelf.create!
226
+ shelf.books.create!(title: "physical", name: "alias")
227
+ Book.alias_attribute :title, :name
228
+
229
+ expect(Shelf.search("physical")).to eq [shelf]
230
+ expect(Shelf.search("alias")).to be_empty
231
+ end
232
+ end
233
+
234
+ context "with a trusted SQL expression as the association source" do
235
+ with_model :Book do
236
+ table do |t|
237
+ t.json :metadata
238
+ t.belongs_to :shelf
239
+ end
240
+
241
+ model do
242
+ belongs_to :shelf
243
+ end
244
+ end
245
+
246
+ with_model :Shelf do
247
+ table
248
+
249
+ model do
250
+ include PgSearch::Model
251
+
252
+ has_many :books
253
+
254
+ pg_search_scope :search,
255
+ associated_against: {books: Arel.sql("metadata->>'title'")}
256
+ end
257
+ end
258
+
259
+ it "evaluates the expression before aggregating the associated rows" do
260
+ shelf = Shelf.create!
261
+ shelf.books.create!(metadata: {title: "Hello"})
262
+ shelf.books.create!(metadata: {title: "world"})
263
+
264
+ expect(Shelf.search("Hello world")).to eq [shelf]
265
+ expect(Shelf.search("title")).to be_empty
266
+ end
267
+ end
268
+
145
269
  context "when across multiple associations" do
146
270
  context "when on different tables" do
147
271
  with_model :FirstAssociatedModel do
@@ -284,6 +408,7 @@ describe "a pg_search_scope" do
284
408
 
285
409
  model do
286
410
  include PgSearch::Model
411
+
287
412
  belongs_to :another_model, class_name: "AssociatedModel"
288
413
 
289
414
  pg_search_scope :with_associated, associated_against: {another_model: %i[title author]}
@@ -337,6 +462,7 @@ describe "a pg_search_scope" do
337
462
 
338
463
  model do
339
464
  include PgSearch::Model
465
+
340
466
  belongs_to :another_model, class_name: "AssociatedModel"
341
467
 
342
468
  pg_search_scope :with_associated, associated_against: {another_model: :number}
@@ -368,6 +494,7 @@ describe "a pg_search_scope" do
368
494
  model do
369
495
  has_many :children
370
496
  include PgSearch::Model
497
+
371
498
  pg_search_scope :search_name, against: :name
372
499
  end
373
500
  end
@@ -398,6 +525,8 @@ describe "a pg_search_scope" do
398
525
 
399
526
  context "when merging a pg_search_scope into another model's scope" do
400
527
  with_model :ModelWithAssociation do
528
+ table
529
+
401
530
  model do
402
531
  has_many :associated_models
403
532
  end
@@ -411,6 +540,7 @@ describe "a pg_search_scope" do
411
540
 
412
541
  model do
413
542
  include PgSearch::Model
543
+
414
544
  belongs_to :model_with_association
415
545
 
416
546
  pg_search_scope :search_content, against: :content
@@ -444,6 +574,8 @@ describe "a pg_search_scope" do
444
574
 
445
575
  context "when chained onto a has_many association" do
446
576
  with_model :Company do
577
+ table
578
+
447
579
  model do
448
580
  has_many :positions
449
581
  end
@@ -457,6 +589,7 @@ describe "a pg_search_scope" do
457
589
 
458
590
  model do
459
591
  include PgSearch::Model
592
+
460
593
  pg_search_scope :search, against: :title, using: %i[tsearch trigram]
461
594
  end
462
595
  end
@@ -5,6 +5,8 @@ require "active_support/core_ext/kernel/reporting"
5
5
 
6
6
  describe "Including the deprecated PgSearch module" do
7
7
  with_model :SomeModel do
8
+ table
9
+
8
10
  model do
9
11
  silence_warnings do
10
12
  include PgSearch
@@ -12,7 +14,9 @@ describe "Including the deprecated PgSearch module" do
12
14
  end
13
15
  end
14
16
 
15
- with_model :AnotherModel
17
+ with_model :AnotherModel do
18
+ table
19
+ end
16
20
 
17
21
  it "includes PgSearch::Model" do
18
22
  expect(SomeModel.ancestors).to include PgSearch::Model
@@ -11,6 +11,7 @@ describe "pagination" do
11
11
 
12
12
  model do
13
13
  include PgSearch::Model
14
+
14
15
  pg_search_scope :search_name, against: :name
15
16
 
16
17
  def self.page(page_number)
@@ -14,6 +14,7 @@ describe "an Active Record model which includes PgSearch" do
14
14
 
15
15
  model do
16
16
  include PgSearch::Model
17
+
17
18
  belongs_to :parent_model
18
19
  end
19
20
  end
@@ -24,6 +25,7 @@ describe "an Active Record model which includes PgSearch" do
24
25
 
25
26
  model do
26
27
  include PgSearch::Model
28
+
27
29
  has_many :models_with_pg_search
28
30
  scope :active, -> { where(active: true) }
29
31
  end
@@ -238,6 +240,7 @@ describe "an Active Record model which includes PgSearch" do
238
240
 
239
241
  model do
240
242
  include PgSearch::Model
243
+
241
244
  belongs_to :person
242
245
  pg_search_scope :search_city, against: [:city]
243
246
  end
@@ -250,6 +253,7 @@ describe "an Active Record model which includes PgSearch" do
250
253
 
251
254
  model do
252
255
  include PgSearch::Model
256
+
253
257
  has_many :houses
254
258
  pg_search_scope :named, against: [:name]
255
259
  scope :with_house_in_city, lambda { |city|
@@ -1046,6 +1050,7 @@ describe "an Active Record model which includes PgSearch" do
1046
1050
 
1047
1051
  model do
1048
1052
  include PgSearch::Model
1053
+
1049
1054
  has_many :comments
1050
1055
  end
1051
1056
  end
@@ -1083,10 +1088,65 @@ describe "an Active Record model which includes PgSearch" do
1083
1088
  it "finds by a combination of the two" do
1084
1089
  expect(Post.search_by_content_with_tsvector("phooey commentone").map(&:id)).to eq([expected.id])
1085
1090
  end
1091
+
1092
+ it "finds by the tsvector column when ordering by an associated table" do
1093
+ # Reference the physical table name that Active Record would normally
1094
+ # leave unaliased. The old string rank join made AliasTracker think the
1095
+ # name was already used and alias this outer join, breaking the order.
1096
+ # https://github.com/Casecommons/pg_search/issues/206
1097
+ results = Post
1098
+ .joins(:comments)
1099
+ .search_by_content_with_tsvector("phooey")
1100
+ .order(Comment.table_name => {id: :asc})
1101
+
1102
+ expect(results).to eq([expected])
1103
+ end
1104
+
1105
+ it "finds by the tsvector column when ordering by an association alias" do
1106
+ results = Post
1107
+ .joins(:comments)
1108
+ .search_by_content_with_tsvector("phooey")
1109
+ .order(comments: {id: :asc})
1110
+
1111
+ expect(results).to eq([expected])
1112
+ end
1113
+ end
1114
+
1115
+ context "with quoted identifiers and a rank attribute alias" do
1116
+ with_model :Article do
1117
+ table primary_key: "ArticleID" do |t|
1118
+ t.text :content
1119
+ t.tsvector "SearchVector"
1120
+ t.integer :importance
1121
+ end
1122
+
1123
+ model do
1124
+ include PgSearch::Model
1125
+
1126
+ alias_attribute :rank, :importance
1127
+ pg_search_scope :search_content,
1128
+ using: {tsearch: {tsvector_column: "SearchVector"}}
1129
+ end
1130
+ end
1131
+
1132
+ it "searches the physical vector and selects the synthetic rank" do
1133
+ article = Article.create!(content: "phooey", importance: 10)
1134
+ Article.update_all(
1135
+ %("SearchVector" = to_tsvector('simple', "content"))
1136
+ )
1137
+
1138
+ result = Article.search_content("phooey").with_pg_search_rank.first
1139
+
1140
+ expect(result).to eq(article)
1141
+ expect(result.pg_search_rank).to be_a(Float)
1142
+ expect(result.pg_search_rank).not_to eq(result.importance)
1143
+ end
1086
1144
  end
1087
1145
 
1088
1146
  context "when using multiple tsvector columns" do
1089
1147
  with_model :ModelWithTsvector do
1148
+ table
1149
+
1090
1150
  model do
1091
1151
  include PgSearch::Model
1092
1152
 
@@ -1185,7 +1245,7 @@ describe "an Active Record model which includes PgSearch" do
1185
1245
  end
1186
1246
 
1187
1247
  context "when the query includes accents" do
1188
- let(:term) { "L#{%w[‘ ’ ʻ ʼ].sample}Content" }
1248
+ let(:term) { "L#{%w[‘ ’ ʻ ʼ ʹ ʽ ˈ ' ʼn].sample}Content" }
1189
1249
  let(:included) { ModelWithPgSearch.create!(title: "Weird #{term}") }
1190
1250
  let(:results) { ModelWithPgSearch.search_title_without_accents(term) }
1191
1251
 
@@ -1199,6 +1259,23 @@ describe "an Active Record model which includes PgSearch" do
1199
1259
  end
1200
1260
  end
1201
1261
 
1262
+ context "when passed an :order_within_rank expression" do
1263
+ before do
1264
+ ModelWithPgSearch.pg_search_scope :search_content_ordered_by_importance,
1265
+ against: :content,
1266
+ order_within_rank: "importance DESC"
1267
+ end
1268
+
1269
+ it "breaks ties in rank by the custom expression" do
1270
+ # Both records match equally; importance determines order
1271
+ low = ModelWithPgSearch.create!(content: "foo", importance: 1)
1272
+ high = ModelWithPgSearch.create!(content: "foo", importance: 5)
1273
+
1274
+ results = ModelWithPgSearch.search_content_ordered_by_importance("foo")
1275
+ expect(results).to eq([high, low])
1276
+ end
1277
+ end
1278
+
1202
1279
  context "when passed a :ranked_by expression" do
1203
1280
  before do
1204
1281
  ModelWithPgSearch.pg_search_scope :search_content_with_default_rank,
@@ -12,6 +12,7 @@ describe "a pg_search_scope on an STI subclass" do
12
12
 
13
13
  model do
14
14
  include PgSearch::Model
15
+
15
16
  pg_search_scope :search_content, against: :content
16
17
  end
17
18
  end
@@ -52,6 +53,7 @@ describe "a pg_search_scope on an STI subclass" do
52
53
 
53
54
  model do
54
55
  include PgSearch::Model
56
+
55
57
  self.inheritance_column = "custom_type"
56
58
  pg_search_scope :search_content, against: :content
57
59
  end