Skip to content

Commit 00a4fd8

Browse files
committed
Handle rank joins on subquery
1 parent ccc2e82 commit 00a4fd8

File tree

2 files changed

+58
-9
lines changed

2 files changed

+58
-9
lines changed

lib/pg_search/scope_options.rb

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,15 @@ def increment_counter
7979
delegate :connection, :quoted_table_name, to: :model
8080

8181
def subquery
82-
model
83-
.unscoped
84-
.select("#{primary_key} AS pg_search_id")
85-
.select("#{rank} AS rank")
82+
query = model.unscoped
83+
84+
if composite_primary_key?
85+
query = query.select(model.primary_key.map.with_index(1) { |part, index| "#{quoted_column_name(part)} AS pg_search_id_#{index}" })
86+
else
87+
query = query.select("#{primary_key} AS pg_search_id")
88+
end
89+
90+
query.select("#{rank} AS rank")
8691
.joins(subquery_join)
8792
.where(conditions)
8893
.limit(nil)
@@ -101,11 +106,10 @@ def order_within_rank
101106
end
102107

103108
def primary_key
104-
if model.primary_key.is_a?(Array)
105-
model.primary_key.map { |part| "#{quoted_table_name}.#{connection.quote_column_name(part)}" }
106-
.join(',')
109+
if composite_primary_key?
110+
model.primary_key.map { |part| quoted_column_name(part) }.join(',')
107111
else
108-
"#{quoted_table_name}.#{connection.quote_column_name(model.primary_key)}"
112+
quoted_column_name(model.primary_key)
109113
end
110114
end
111115

@@ -147,7 +151,14 @@ def rank
147151
end
148152

149153
def rank_join(rank_table_alias)
150-
"INNER JOIN (#{subquery.to_sql}) AS #{rank_table_alias} ON #{primary_key} = #{rank_table_alias}.pg_search_id"
154+
join_condition = if composite_primary_key?
155+
model.primary_key.map.with_index(1) { |part, index| "#{quoted_column_name(part)} = #{rank_table_alias}.pg_search_id_#{index}" }
156+
.join(" AND ")
157+
else
158+
"#{primary_key} = #{rank_table_alias}.pg_search_id"
159+
end
160+
161+
"INNER JOIN (#{subquery.to_sql}) AS #{rank_table_alias} ON #{join_condition}"
151162
end
152163

153164
def include_table_aliasing_for_rank(scope)
@@ -157,5 +168,17 @@ def include_table_aliasing_for_rank(scope)
157168
new_scope.instance_eval { extend PgSearchRankTableAliasing }
158169
end
159170
end
171+
172+
def composite_primary_key?
173+
model.primary_key.is_a?(Array)
174+
end
175+
176+
def composite_primary_key_length
177+
model.primary_key.length
178+
end
179+
180+
def quoted_column_name(column)
181+
"#{quoted_table_name}.#{connection.quote_column_name(column)}"
182+
end
160183
end
161184
end
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# frozen_string_literal: true
2+
3+
require "spec_helper"
4+
5+
describe "composite_primary_key" do
6+
with_model :CompositePrimaryKeyModel do
7+
table primary_key: [:prefix, :postfix] do |t|
8+
t.string :prefix
9+
t.string :postfix
10+
t.string :name
11+
end
12+
13+
model do
14+
include PgSearch::Model
15+
self.primary_key = [:prefix, :postfix]
16+
pg_search_scope :search_name, against: :name
17+
end
18+
end
19+
20+
before { CompositePrimaryKeyModel.create!(id: ["prefix", "postfix"], name: "bar") }
21+
let!(:record_1) { CompositePrimaryKeyModel.create!(id: ["prefix_2", "postfix_2"], name: "foo") }
22+
23+
it "searches without any issues" do
24+
expect(CompositePrimaryKeyModel.search_name("foo")).to eq([record_1])
25+
end
26+
end

0 commit comments

Comments
 (0)