File tree Expand file tree Collapse file tree 5 files changed +69
-1
lines changed Expand file tree Collapse file tree 5 files changed +69
-1
lines changed Original file line number Diff line number Diff line change @@ -251,6 +251,20 @@ the order indicator arrow by passing `hide_indicator: true` in the sort link:
251251 default_order: { last_name: 'asc', first_name: 'desc' }) %>
252252```
253253
254+ #### PostgreSQL's sort option
255+
256+ The ` NULLS FIRST ` and ` NULLS LAST ` options can be used to determine whether nulls appear before or after non-null values in the sort ordering.
257+
258+ You may want to configure it like this:
259+
260+ ``` rb
261+ Ransack .configure do |c |
262+ c.postgres_fields_sort_option = :nulls_first # or :nulls_last
263+ end
264+ ```
265+
266+ See this feature: https://www.postgresql.org/docs/13/queries-order.html
267+
254268### Advanced Mode
255269
256270"Advanced" searches (ab)use Rails' nested attributes functionality in order to
Original file line number Diff line number Diff line change @@ -42,6 +42,13 @@ def evaluate(search, opts = {})
4242 if scope_or_sort . is_a? ( Symbol )
4343 relation = relation . send ( scope_or_sort )
4444 else
45+ case Ransack . options [ :postgres_fields_sort_option ]
46+ when :nulls_first
47+ scope_or_sort = scope_or_sort . direction == :asc ? "#{ scope_or_sort . to_sql } NULLS FIRST" : "#{ scope_or_sort . to_sql } NULLS LAST"
48+ when :nulls_last
49+ scope_or_sort = scope_or_sort . direction == :asc ? "#{ scope_or_sort . to_sql } NULLS LAST" : "#{ scope_or_sort . to_sql } NULLS FIRST"
50+ end
51+
4552 relation = relation . order ( scope_or_sort )
4653 end
4754 end
Original file line number Diff line number Diff line change @@ -33,7 +33,8 @@ def []=(key, value)
3333 :up_arrow => '▼' . freeze ,
3434 :down_arrow => '▲' . freeze ,
3535 :default_arrow => nil ,
36- :sanitize_scope_args => true
36+ :sanitize_scope_args => true ,
37+ :postgres_fields_sort_option => nil
3738 }
3839
3940 def configure
@@ -141,6 +142,21 @@ def sanitize_custom_scope_booleans=(boolean)
141142 self . options [ :sanitize_scope_args ] = boolean
142143 end
143144
145+ # The `NULLS FIRST` and `NULLS LAST` options can be used to determine
146+ # whether nulls appear before or after non-null values in the sort ordering.
147+ #
148+ # User may want to configure it like this:
149+ #
150+ # Ransack.configure do |c|
151+ # c.postgres_fields_sort_option = :nulls_first # or :nulls_last
152+ # end
153+ #
154+ # See this feature: https://www.postgresql.org/docs/13/queries-order.html
155+ #
156+ def postgres_fields_sort_option = ( setting )
157+ self . options [ :postgres_fields_sort_option ] = setting
158+ end
159+
144160 # By default, Ransack displays sort order indicator arrows in sort links.
145161 # The default may be globally overridden in an initializer file like
146162 # `config/initializers/ransack.rb` as follows:
Original file line number Diff line number Diff line change @@ -173,5 +173,15 @@ module Ransack
173173 . to eq false
174174 end
175175 end
176+
177+ it "PG's sort option" , if : ::ActiveRecord ::Base . connection . adapter_name == "PostgreSQL" do
178+ default = Ransack . options . clone
179+
180+ Ransack . configure { |c | c . postgres_fields_sort_option = :nulls_first }
181+
182+ expect ( Ransack . options [ :postgres_fields_sort_option ] ) . to eq :nulls_first
183+
184+ Ransack . options = default
185+ end
176186 end
177187end
Original file line number Diff line number Diff line change @@ -533,6 +533,27 @@ def remove_quotes_and_backticks(str)
533533 @s . sorts = 'id asc'
534534 expect ( @s . result . first . id ) . to eq 1
535535 end
536+
537+ it "PG's sort option" , if : ::ActiveRecord ::Base . connection . adapter_name == "PostgreSQL" do
538+ default = Ransack . options . clone
539+
540+ s = Search . new ( Person , s : 'name asc' )
541+ expect ( s . result . to_sql ) . to eq "SELECT \" people\" .* FROM \" people\" ORDER BY \" people\" .\" name\" ASC"
542+
543+ Ransack . configure { |c | c . postgres_fields_sort_option = :nulls_first }
544+ s = Search . new ( Person , s : 'name asc' )
545+ expect ( s . result . to_sql ) . to eq "SELECT \" people\" .* FROM \" people\" ORDER BY \" people\" .\" name\" ASC NULLS FIRST"
546+ s = Search . new ( Person , s : 'name desc' )
547+ expect ( s . result . to_sql ) . to eq "SELECT \" people\" .* FROM \" people\" ORDER BY \" people\" .\" name\" DESC NULLS LAST"
548+
549+ Ransack . configure { |c | c . postgres_fields_sort_option = :nulls_last }
550+ s = Search . new ( Person , s : 'name asc' )
551+ expect ( s . result . to_sql ) . to eq "SELECT \" people\" .* FROM \" people\" ORDER BY \" people\" .\" name\" ASC NULLS LAST"
552+ s = Search . new ( Person , s : 'name desc' )
553+ expect ( s . result . to_sql ) . to eq "SELECT \" people\" .* FROM \" people\" ORDER BY \" people\" .\" name\" DESC NULLS FIRST"
554+
555+ Ransack . options = default
556+ end
536557 end
537558
538559 describe '#method_missing' do
You can’t perform that action at this time.
0 commit comments