diff --git a/lib/administrate/order.rb b/lib/administrate/order.rb index 3c083b41b0..88d09b1b2a 100644 --- a/lib/administrate/order.rb +++ b/lib/administrate/order.rb @@ -6,11 +6,13 @@ def initialize(attribute = nil, direction = nil) end def apply(relation) - if relation.columns_hash.keys.include?(attribute.to_s) - relation.order("#{attribute} #{direction}") - else - relation - end + return order_by_association(relation) if + !reflect_association(relation).nil? + + return relation.reorder("#{attribute} #{direction}") if + relation.columns_hash.keys.include?(attribute.to_s) + + relation end def ordered_by?(attr) @@ -41,5 +43,36 @@ def reversed_direction_param_for(attr) def opposite_direction direction.to_sym == :asc ? :desc : :asc end + + def order_by_association(relation) + return order_by_count(relation) if has_many_attribute?(relation) + + return order_by_id(relation) if belongs_to_attribute?(relation) + + relation + end + + def order_by_count(relation) + relation. + left_joins(attribute.to_sym). + group(:id). + reorder("COUNT(#{attribute}.id) #{direction}") + end + + def order_by_id(relation) + relation.reorder("#{attribute}_id #{direction}") + end + + def has_many_attribute?(relation) + reflect_association(relation).macro == :has_many + end + + def belongs_to_attribute?(relation) + reflect_association(relation).macro == :belongs_to + end + + def reflect_association(relation) + relation.klass.reflect_on_association(attribute.to_s) + end end end