Skip to content

Commit

Permalink
Add ability to sort on multiple fields
Browse files Browse the repository at this point in the history
  • Loading branch information
westonganger committed Oct 14, 2021
1 parent b15bf6f commit f30de2f
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 9 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ CHANGELOG
---------

- **Unreleased - [View Diff](https://github.com/westonganger/active_sort_order/compare/v0.9.2...master)**
* Nothing yet
* Allow ability to sort on multiple fields

- **v0.9.2 - Apr 28, 2021 - [View Diff](https://github.com/westonganger/active_sort_order/compare/v0.9.1...v0.9.2)**
* Fix deprecation warning in Rails 6.1 for `reorder(nil)`
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,12 @@ In the below examples we are within a controller and are using the params as our
```ruby
# app/controllers/posts_controller.rb

if params[:sort] == "number_str"
case params[:sort]
when "number_str"
sort_col_sql = "CAST(posts.number_str AS int)"
when "user"
### To sort on multiple fields pass in an Array
sort_col_sql = ["users.first_name", "users.last_name"]
else
sort_col_sql = params[:sort]
end
Expand All @@ -49,6 +53,8 @@ Post.all.sort_order(sort_col_sql, params[:direction], base_sort_order: "lower(nu
Post.all.sort_order(sort_col_sql, params[:direction])
```

## Sorting on multiple columns

##### Method Definition:

`sort_order(sort_col_sql = nil, sort_direction_sql = nil, base_sort_order: true)`
Expand Down
18 changes: 11 additions & 7 deletions lib/active_sort_order/concerns/sort_order_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ module SortOrderConcern
included do

scope :sort_order, ->(sort_col_sql = nil, sort_direction_sql = nil, base_sort_order: true){
if [String, Symbol, NilClass].exclude?(sort_col_sql.class)
raise ArgumentError.new("Invalid first argument `sort_col_sql`, expecting a a String or Symbol")
end

if sort_col_sql.present?
sort_col_sql = sort_col_sql.to_s
if sort_col_sql.is_a?(Array)
sort_col_sql = sort_col_sql.map{|x| x.to_s }
else
sort_col_sql = sort_col_sql.to_s
end

### SORT DIRECTION HANDLING
if sort_direction_sql.is_a?(Symbol)
Expand All @@ -20,7 +20,7 @@ module SortOrderConcern
if sort_direction_sql.nil? || (sort_direction_sql.is_a?(String) && sort_direction_sql == "")
sort_direction_sql = "ASC"
elsif !sort_direction_sql.is_a?(String)
raise ArgumentError.new("Invalid second argument `sort_direction_sql`, expecting a a String or Symbol")
raise ArgumentError.new("Invalid second argument `sort_direction_sql`, expecting a String or Symbol")
else
valid_directions = [
"ASC",
Expand All @@ -41,7 +41,11 @@ module SortOrderConcern
end
end

sql_str = "#{sort_col_sql} #{sort_direction_sql}"
if !sort_col_sql.is_a?(Array)
sort_col_sql = [sort_col_sql]
end

sql_str = sort_col_sql.map{|x| "#{x} #{sort_direction_sql}" }.join(", ")
end

### BASE SORT ORDER HANDLING
Expand Down
20 changes: 20 additions & 0 deletions test/unit/active_sort_order_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,24 @@ def test_base_sort_order_and_sort
end
end

def test_sort_on_multiple_fields
assert_equal Post.all.count, DATA[:posts].count

expected = DATA[:posts].sort_by{|item| [item.b, item.a] }

sorted = PostWithBaseOrderA.all.sort_order([:b, :a], :asc)

sorted.each_with_index do |item, i|
assert_equal expected[i].id, item.id
end

expected = DATA[:posts].sort_by{|item| [item.b, item.a] }.reverse

sorted = PostWithBaseOrderA.all.sort_order([:b, :a], :desc)

sorted.each_with_index do |item, i|
assert_equal expected[i].id, item.id
end
end

end

0 comments on commit f30de2f

Please sign in to comment.