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 @@ -250,6 +250,20 @@ the order indicator arrow by passing `hide_indicator: true` in the sort link:
250250 default_order: { last_name: 'asc', first_name: 'desc' }) %>
251251```
252252
253+ #### PostgreSQL's sort option
254+
255+ 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.
256+
257+ You may want to configure it like this:
258+
259+ ``` rb
260+ Ransack .configure do |c |
261+ c.postgres_fields_sort_option = :nulls_first # or :nulls_last
262+ end
263+ ```
264+
265+ See this feature: https://www.postgresql.org/docs/13/queries-order.html
266+
253267### Advanced Mode
254268
255269"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 @@ -507,6 +507,27 @@ def remove_quotes_and_backticks(str)
507507 @s . sorts = 'id asc'
508508 expect ( @s . result . first . id ) . to eq 1
509509 end
510+
511+ it "PG's sort option" , if : ::ActiveRecord ::Base . connection . adapter_name == "PostgreSQL" do
512+ default = Ransack . options . clone
513+
514+ s = Search . new ( Person , s : 'name asc' )
515+ expect ( s . result . to_sql ) . to eq "SELECT \" people\" .* FROM \" people\" ORDER BY \" people\" .\" name\" ASC"
516+
517+ Ransack . configure { |c | c . postgres_fields_sort_option = :nulls_first }
518+ s = Search . new ( Person , s : 'name asc' )
519+ expect ( s . result . to_sql ) . to eq "SELECT \" people\" .* FROM \" people\" ORDER BY \" people\" .\" name\" ASC NULLS FIRST"
520+ s = Search . new ( Person , s : 'name desc' )
521+ expect ( s . result . to_sql ) . to eq "SELECT \" people\" .* FROM \" people\" ORDER BY \" people\" .\" name\" DESC NULLS LAST"
522+
523+ Ransack . configure { |c | c . postgres_fields_sort_option = :nulls_last }
524+ s = Search . new ( Person , s : 'name asc' )
525+ expect ( s . result . to_sql ) . to eq "SELECT \" people\" .* FROM \" people\" ORDER BY \" people\" .\" name\" ASC NULLS LAST"
526+ s = Search . new ( Person , s : 'name desc' )
527+ expect ( s . result . to_sql ) . to eq "SELECT \" people\" .* FROM \" people\" ORDER BY \" people\" .\" name\" DESC NULLS FIRST"
528+
529+ Ransack . options = default
530+ end
510531 end
511532
512533 describe '#method_missing' do
You can’t perform that action at this time.
0 commit comments