Active Admin: sorting on multiple columns
This is also a monkey patch:
Create a new file in config/initializers or in the lib folder: multiple_columns_sorting.rb
module ActiveAdmin
class ResourceController < BaseController
module DataAccess
def apply_sorting(chain)
params[:order] ||= active_admin_config.sort_order
orders = []
params[:order].split('_and_').each do |fragment|
order_clause = OrderClause.new fragment
if order_clause.valid?
orders << order_clause.to_sql(active_admin_config)
end
end
if orders.empty?
chain
else
chain.reorder(orders.shift).order(orders)
end
end
end
end
end
Restart the server. Now you can use several columns name separeted by "_and_"
. For example:
config.sort_order = 'first_name_desc_and_last_name_asc'
active_admin config.sort for two columns
ActiveAdmin suggests overwrite the find_collection
method, which returns an ActiveRecord::Relation
. But I prefer add the order
to it's output.
ActiveAdmin.register Show do
controller do
def find_collection(options = {})
super.reorder(rider_last_name: :asc, start_time: :asc)
end
end
...
end
Although it works, this overwrite the user option of click on a column.
Alternative
You can do the same with scoped_collection
, which is called at the start of find_collection
, but it does not work unless you add active_admin_config.sort_order = ''
to the controller. This way:
controller do
active_admin_config.sort_order = ''
def scoped_collection
super.reorder(rider_last_name: :asc, start_time: :asc)
end
end
Now, if we want to reorder before and, after that take care of the user params (and do not overwrite them). This is the way.
Note: I did use active_admin_config.sort_order
and not config.sort_order
.
Also, the sort_order
option, ends as a param of OrderClause.new
call, which expect for only one sort field, see here and here.
Activeadmin sortable by multiple columns
I've faced same issue. Judging by source code this feature isn't supported
def sort_order(chain)
params[:order] ||= active_admin_config.sort_order
if params[:order] && params[:order] =~ /^([\w\_\.]+)_(desc|asc)$/
column = $1
order = $2
table = active_admin_config.resource_table_name
table_column = (column =~ /\./) ? column :
"#{table}.#{active_admin_config.resource_quoted_column_name(column)}"
chain.reorder("#{table_column} #{order}")
else
chain # just return the chain
end
end
But there is monkey patch solution.
Sort multiple joins table_for in rails activeadmin
Here is an example of something you could do (even if it's not ideal...):
# app/admin/users.rb
show do
tab do
# Use `split` in case you have columns like `created_at` (which won't work with `gsub('_', ' ')`)
# In case `params[:order]` isn't defined, `step DESC` is the default order
split_order = params[:order]&.split('_') || ['step', 'desc']
order_direction = split_order.pop
order_column = split_order.join('_')
supports =
user
.supports
.joins('LEFT JOIN payments ON payments.support_id = supports.id')
.order(order_column => order_direction)
table_for supports, sortable: true do
column 'step', sortable: :step { |support| support.step }
column 'date', sortable: 'payments.date' { |support| support.payment.date }
end
end
end
How to make a column sortable in Dashboard in ActiveAdmin?
In case someone needs help in the future to customize the sorting:
test_order = if params[:order]
params[:order].gsub(/[^a-z_]/,'').gsub(/_(asc|desc)$/, ' \1') #sanitize and convert to order expression
else
"status desc" #default
end
table_for Test.all.order(test_order), sortable: true, class: 'index_table' do
column "Name", :name, sortable: false #to hide sorting name
column :status
end
end
end
resource taken from: https://github.com/activeadmin/activeadmin/issues/4483#issuecomment-237073696
How can ActiveAdmin start sorting columns after the first click on columns' header in ascending order?
Unfortunately what you want to do doesn't seem configurable because desc
, the default sort, is hard-coded. However, if you would like a monkey patch, you can put code below in config/initializers/active_admin.rb
which overrides the default behaviour.
module ActiveAdmin
module Views
class TableFor < Arbre::HTML::Table
def order_for_sort_key(sort_key)
current_key, current_order = current_sort
return 'asc' unless current_key == sort_key
current_order == 'desc' ? 'asc' : 'desc'
end
end
end
end
ActiveAdmin how to sort column with associations
FIXED
column :type, :sortable => 'types.category'
Related Topics
Is There a Ruby Http Client Library with a Response Cache
How to Create a Form in Rails Without Having to Use Form_For and a Model Instance
Run Code Only If Script Called from the Command Line
Run a Ruby Library from the Command-Line
Activeadmin Forbiddenattributeserror
Implementing Bayesian Classifier in Ruby
"Gem Update --System Is Disabled on Debian" Error
Referencing Model with String Input
How to Deal with Ruby 2.1.2 Memory Leaks
Devise Nomethoderror 'For' Parametersanitizer
How to Find Best Matching Element in Array of Numbers
Ruby Time Object Converted from Float Doesn't Equal to Orignial Time Object
Ruby Find and Return Objects in an Array Based on an Attribute