Skip to content

Commit

Permalink
Order attributes by association if it exists
Browse files Browse the repository at this point in the history
Adding an order clause to the relation for an associated
attribute was having no effect on the dashboard's sorting.
When the order is applied, the current relation will check
if the attribute is an association and reorder by count
on the attribute's id column or on the relation's
{attribute}_id column following the Rails convention
of naming FK columns. The relation order method was
changed to reorder to override any default scoping
that may exist for the relation.

thoughtbot#471
  • Loading branch information
rnice01 committed Oct 20, 2017
1 parent 3366bd1 commit 9508763
Showing 1 changed file with 38 additions and 5 deletions.
43 changes: 38 additions & 5 deletions lib/administrate/order.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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

0 comments on commit 9508763

Please sign in to comment.