Add ability to config PostgreSQL ORDER BY ... NULLS FIRST or NULLS LAST, close #1125
This commit is contained in:
parent
150eeb2f08
commit
2f5c6f60e8
14
README.md
14
README.md
|
@ -250,6 +250,20 @@ the order indicator arrow by passing `hide_indicator: true` in the sort link:
|
|||
default_order: { last_name: 'asc', first_name: 'desc' }) %>
|
||||
```
|
||||
|
||||
#### PostgreSQL's sort option
|
||||
|
||||
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.
|
||||
|
||||
You may want to configure it like this:
|
||||
|
||||
```rb
|
||||
Ransack.configure do |c|
|
||||
c.postgres_fields_sort_option = :nulls_first # or :nulls_last
|
||||
end
|
||||
```
|
||||
|
||||
See this feature: https://www.postgresql.org/docs/13/queries-order.html
|
||||
|
||||
### Advanced Mode
|
||||
|
||||
"Advanced" searches (ab)use Rails' nested attributes functionality in order to
|
||||
|
|
|
@ -42,6 +42,13 @@ module Ransack
|
|||
if scope_or_sort.is_a?(Symbol)
|
||||
relation = relation.send(scope_or_sort)
|
||||
else
|
||||
case Ransack.options[:postgres_fields_sort_option]
|
||||
when :nulls_first
|
||||
scope_or_sort = scope_or_sort.direction == :asc ? "#{scope_or_sort.to_sql} NULLS FIRST" : "#{scope_or_sort.to_sql} NULLS LAST"
|
||||
when :nulls_last
|
||||
scope_or_sort = scope_or_sort.direction == :asc ? "#{scope_or_sort.to_sql} NULLS LAST" : "#{scope_or_sort.to_sql} NULLS FIRST"
|
||||
end
|
||||
|
||||
relation = relation.order(scope_or_sort)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -33,7 +33,8 @@ module Ransack
|
|||
:up_arrow => '▼'.freeze,
|
||||
:down_arrow => '▲'.freeze,
|
||||
:default_arrow => nil,
|
||||
:sanitize_scope_args => true
|
||||
:sanitize_scope_args => true,
|
||||
:postgres_fields_sort_option => nil
|
||||
}
|
||||
|
||||
def configure
|
||||
|
@ -141,6 +142,21 @@ module Ransack
|
|||
self.options[:sanitize_scope_args] = boolean
|
||||
end
|
||||
|
||||
# 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.
|
||||
#
|
||||
# User may want to configure it like this:
|
||||
#
|
||||
# Ransack.configure do |c|
|
||||
# c.postgres_fields_sort_option = :nulls_first # or :nulls_last
|
||||
# end
|
||||
#
|
||||
# See this feature: https://www.postgresql.org/docs/13/queries-order.html
|
||||
#
|
||||
def postgres_fields_sort_option=(setting)
|
||||
self.options[:postgres_fields_sort_option] = setting
|
||||
end
|
||||
|
||||
# By default, Ransack displays sort order indicator arrows in sort links.
|
||||
# The default may be globally overridden in an initializer file like
|
||||
# `config/initializers/ransack.rb` as follows:
|
||||
|
|
|
@ -173,5 +173,15 @@ module Ransack
|
|||
.to eq false
|
||||
end
|
||||
end
|
||||
|
||||
it "PG's sort option", if: ::ActiveRecord::Base.connection.adapter_name == "PostgreSQL" do
|
||||
default = Ransack.options.clone
|
||||
|
||||
Ransack.configure { |c| c.postgres_fields_sort_option = :nulls_first }
|
||||
|
||||
expect(Ransack.options[:postgres_fields_sort_option]).to eq :nulls_first
|
||||
|
||||
Ransack.options = default
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -507,6 +507,27 @@ module Ransack
|
|||
@s.sorts = 'id asc'
|
||||
expect(@s.result.first.id).to eq 1
|
||||
end
|
||||
|
||||
it "PG's sort option", if: ::ActiveRecord::Base.connection.adapter_name == "PostgreSQL" do
|
||||
default = Ransack.options.clone
|
||||
|
||||
s = Search.new(Person, s: 'name asc')
|
||||
expect(s.result.to_sql).to eq "SELECT \"people\".* FROM \"people\" ORDER BY \"people\".\"name\" ASC"
|
||||
|
||||
Ransack.configure { |c| c.postgres_fields_sort_option = :nulls_first }
|
||||
s = Search.new(Person, s: 'name asc')
|
||||
expect(s.result.to_sql).to eq "SELECT \"people\".* FROM \"people\" ORDER BY \"people\".\"name\" ASC NULLS FIRST"
|
||||
s = Search.new(Person, s: 'name desc')
|
||||
expect(s.result.to_sql).to eq "SELECT \"people\".* FROM \"people\" ORDER BY \"people\".\"name\" DESC NULLS LAST"
|
||||
|
||||
Ransack.configure { |c| c.postgres_fields_sort_option = :nulls_last }
|
||||
s = Search.new(Person, s: 'name asc')
|
||||
expect(s.result.to_sql).to eq "SELECT \"people\".* FROM \"people\" ORDER BY \"people\".\"name\" ASC NULLS LAST"
|
||||
s = Search.new(Person, s: 'name desc')
|
||||
expect(s.result.to_sql).to eq "SELECT \"people\".* FROM \"people\" ORDER BY \"people\".\"name\" DESC NULLS FIRST"
|
||||
|
||||
Ransack.options = default
|
||||
end
|
||||
end
|
||||
|
||||
describe '#method_missing' do
|
||||
|
|
Loading…
Reference in New Issue