@@ -14,13 +14,12 @@ def initialize(config)
14
14
15
15
def apply ( scope )
16
16
scope = include_table_aliasing_for_rank ( scope )
17
- rank_table_alias = scope . pg_search_rank_table_alias ( include_counter : true )
18
17
19
- scope
20
- . joins ( rank_join ( rank_table_alias ) )
21
- . order ( Arel . sql ( " #{ rank_table_alias } .rank DESC, #{ order_within_rank } " ) )
22
- . extend ( WithPgSearchRank )
23
- . extend ( WithPgSearchHighlight [ feature_for ( :tsearch ) ] )
18
+ if config . associations . any?
19
+ apply_with_inner_join ( scope )
20
+ else
21
+ apply_without_inner_join ( scope )
22
+ end
24
23
end
25
24
26
25
module WithPgSearchHighlight
@@ -54,6 +53,34 @@ def with_pg_search_rank
54
53
end
55
54
end
56
55
56
+ module WithPgSearchRankNoInnerJoin
57
+ def self . []( rank_value )
58
+ Module . new do
59
+ include WithPgSearchRankNoInnerJoin
60
+ define_method ( :rank_value ) { rank_value }
61
+ end
62
+ end
63
+
64
+ def rank_field
65
+ "#{ rank_value } AS pg_search_rank"
66
+ end
67
+
68
+ def rank_value
69
+ raise TypeError , "You need to instantiate this module with []"
70
+ end
71
+
72
+ def with_pg_search_rank
73
+ scope = self
74
+ scope = scope . select ( "#{ table_name } .*" ) unless scope . select_values . any?
75
+ scope . select ( rank_field )
76
+ end
77
+
78
+ def where_pg_search_rank ( value )
79
+ scope = self
80
+ scope . where ( "#{ rank_value } #{ value } " )
81
+ end
82
+ end
83
+
57
84
module PgSearchRankTableAliasing
58
85
def pg_search_rank_table_alias ( include_counter : false )
59
86
components = [ arel_table . name ]
@@ -78,6 +105,24 @@ def increment_counter
78
105
79
106
delegate :connection , :quoted_table_name , to : :model
80
107
108
+ def apply_with_inner_join ( scope )
109
+ rank_table_alias = scope . pg_search_rank_table_alias ( include_counter : true )
110
+
111
+ scope
112
+ . joins ( rank_join ( rank_table_alias ) )
113
+ . order ( Arel . sql ( "#{ rank_table_alias } .rank DESC, #{ order_within_rank } " ) )
114
+ . extend ( WithPgSearchRank )
115
+ . extend ( WithPgSearchHighlight [ feature_for ( :tsearch ) ] )
116
+ end
117
+
118
+ def apply_without_inner_join ( scope )
119
+ scope
120
+ . where ( conditions )
121
+ . order ( Arel . sql ( "#{ rank_order } , #{ order_within_rank } " ) )
122
+ . extend ( WithPgSearchRankNoInnerJoin [ rank ] )
123
+ . extend ( WithPgSearchHighlight [ feature_for ( :tsearch ) ] )
124
+ end
125
+
81
126
def subquery
82
127
model
83
128
. unscoped
@@ -95,7 +140,7 @@ def conditions
95
140
. reject { |_feature_name , feature_options | feature_options && feature_options [ :sort_only ] }
96
141
. map { |feature_name , _feature_options | feature_for ( feature_name ) . conditions }
97
142
98
- or_node ( expressions )
143
+ or_node ( expressions ) . to_sql
99
144
end
100
145
101
146
# https://github.com/rails/rails/pull/51492
@@ -166,6 +211,10 @@ def rank_join(rank_table_alias)
166
211
"INNER JOIN (#{ subquery . to_sql } ) AS #{ rank_table_alias } ON #{ primary_key } = #{ rank_table_alias } .pg_search_id"
167
212
end
168
213
214
+ def rank_order
215
+ "#{ rank } DESC"
216
+ end
217
+
169
218
def include_table_aliasing_for_rank ( scope )
170
219
return scope if scope . included_modules . include? ( PgSearchRankTableAliasing )
171
220
0 commit comments