Make columns of user and ordergroup lists sortable

This commit implements the sort functionality for the user lists (by name, email, last_activity) and ordergroup lists (by name).
It is a first attempt addressing issue #560.
This commit is contained in:
Harald Reingruber 2022-05-27 17:06:25 +02:00 committed by GitHub
parent 8f94403ccf
commit 0a6345c60b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 278 additions and 25 deletions

View file

@ -148,6 +148,29 @@ class Ordergroup < Group
financial_transactions.last.try(:created_on) || created_on
end
def self.sort_by_param(param)
param ||= "name"
sort_param_map = {
"name" => "name",
"name_reverse" => "name DESC",
"members_count" => "count(users.id)",
"members_count_reverse" => "count(users.id) DESC",
"last_user_activity" => "max(users.last_activity)",
"last_user_activity_reverse" => "max(users.last_activity) DESC",
"last_order" => "max(orders.starts)",
"last_order_reverse" => "max(orders.starts) DESC"
}
result = self
result = result.left_joins(:users).group("groups.id") if param.starts_with?("members_count", "last_user_activity")
result = result.left_joins(:orders).group("groups.id") if param.starts_with?("last_order")
# Never pass user input data to Arel.sql() because of SQL Injection vulnerabilities.
# This case here is okay, as param is mapped to the actual order string.
result.order(Arel.sql(sort_param_map[param]))
end
private
# Make sure, that a user can only be in one ordergroup

View file

@ -250,4 +250,27 @@ class User < ApplicationRecord
# this should not be part of the model anyway
{ :id => id, :name => "#{display} (#{ordergroup.try(:name)})" }
end
def self.sort_by_param(param)
param ||= "name"
sort_param_map = {
"nick" => "nick",
"nick_reverse" => "nick DESC",
"name" => "first_name, last_name",
"name_reverse" => "first_name DESC, last_name DESC",
"email" => "users.email",
"email_reverse" => "users.email DESC",
"phone" => "phone",
"phone_reverse" => "phone DESC",
"last_activity" => "last_activity",
"last_activity_reverse" => "last_activity DESC",
"ordergroup" => "IFNULL(groups.type, '') <> 'Ordergroup', groups.name",
"ordergroup_reverse" => "IFNULL(groups.type, '') <> 'Ordergroup', groups.name DESC"
}
# Never pass user input data to Arel.sql() because of SQL Injection vulnerabilities.
# This case here is okay, as param is mapped to the actual order string.
self.eager_load(:groups).order(Arel.sql(sort_param_map[param])) # eager_load is like left_join but without duplicates
end
end