For most models, the default sort order (id desc) is fine. But for a couple of scopes on one of my models, it would make more sense to reverse the order, or order by the updated_at field.
I seem unable to achieve this without breaking other functionality, so I'm hoping someone else might teach me how to do this!
I've tried adding a .order() on the objects I'm returning:
scope :example do |models|
models.order('id asc')
end
This does not seem to have any effect.
I've also tried unscoping, which kind of works. It does sort my objects the way I want to, but it completely breaks all filtering/search functionality.
scope :example do |models|
models.unscoped.order('id asc')
end
What to do?
This works and also ensures that the default sort order to correctly reflected in the UI.
This is overwriting the apply_sorting
method of ActiveAdmin, so all the usual caveats about monkey patching third party gems apply.
module ActiveAdmin
class ResourceController < BaseController
module CallableSortOrder
def apply_sorting(chain)
params[:order] ||= if active_admin_config.sort_order&.respond_to?(:call)
active_admin_config.sort_order.call(self)
else
active_admin_config.sort_order
end
super
end
end
prepend CallableSortOrder
end
end
Use it like this:
config.sort_order = ->(controller) {
controller.params[:scope] == 'something' ? 'created_at_desc' : 'name_asc'
}
use config.sort_order like:
config.sort_order = "updated_at_desc"
Why not make 2 scopes in your model, one for a particular sort order, the other, reversed, then in ActiveAdmin set one as the default?
scope :example_asc, :default => true
scope :example_desc
If that doesn't work for you, perhaps create a controller block in ActiveAdmin that defines what you're trying to do:
controller do
def asc
Model.order('id ASC')
end
def desc
Model.order('id DESC')
end
end
scope :example do |models|
asc
end
scope :example do |models|
desc
end
And finally, I think this answer is probably fairly accurate: https://stackoverflow.com/a/17612718/175825
But you might want to investigate more about how you can implement sort_order
:
For what it's worth, I'm not a fan of ActiveAdmin's skinny docs. Good luck.
You need to use reorder to override the default order, but also be sensitive as to whether ActiveAdmin sorts are being applied
scope :example do |models|
if params[:order].blank? or params[:order] == "id_desc" #default ordering
models.example.reorder('your order SQL here')
else
models.example
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With