Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sort by default_sort on association class. #750

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions lib/administrate/order.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ def initialize(attribute = nil, direction = nil)
def apply(relation)
if relation.columns_hash.keys.include?(attribute.to_s)
relation.order(attribute => direction)
elsif association?(relation)
AssociationOrder.new(relation, attribute, direction).relation_with_order
else
relation
end
Expand All @@ -30,6 +32,12 @@ def order_params_for(attr)

attr_reader :attribute

def association?(relation)
if relation.respond_to? :reflect_on_association
relation.reflect_on_association(attribute)
end
end

def reversed_direction_param_for(attr)
if ordered_by?(attr)
opposite_direction
Expand All @@ -42,4 +50,40 @@ def opposite_direction
direction.to_sym == :asc ? :desc : :asc
end
end

class AssociationOrder
def initialize(relation, attribute, direction)
@relation = relation
@attribute = attribute
@direction = direction
end

def relation_with_order
association ? relation.includes(association.name).order("#{association.plural_name}.#{order_name} #{direction_for_sql}") : relation

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [137/80]

end

def order_name
if association.klass.respond_to? :default_sort
association.klass.default_sort

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use 2 (not 0) spaces for indentation.

else
:name
end
end

def direction_for_sql
if direction.to_sym == :asc
"ASC"
else
"DESC"
end
end

private

def association
relation.reflect_on_association(attribute)
end

attr_reader :relation, :attribute, :direction
end
end
28 changes: 28 additions & 0 deletions spec/lib/administrate/order_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require "administrate/order"
require "rails_helper"

describe Administrate::Order do
describe "#apply" do
Expand Down Expand Up @@ -51,6 +52,33 @@
expect(ordered).to eq(relation)
end
end

context 'when `order` uses an association with no default_sort method' do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

it 'orders by `name` on the associated record by default' do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

order = Administrate::Order.new(:customer, :desc)
relation = Order.all
allow(relation).to receive(:order).and_return(relation)

ordered = order.apply(relation)

expect(relation).to have_received(:order).with('customers.name DESC')

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

expect(ordered).to eq(relation)
end
end

context 'when `order` uses an association with a default_sort method' do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

it 'orders by the attribute given in the default_sort method' do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

order = Administrate::Order.new(:customer, :asc)
relation = Order.all
allow(relation).to receive(:order).and_return(relation)
allow(Customer).to receive(:default_sort).and_return(:updated_at)

ordered = order.apply(relation)

expect(relation).to have_received(:order).with('customers.updated_at ASC')

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.
Line is too long. [82/80]

expect(ordered).to eq(relation)
end
end
end

describe "#ordered_by?" do
Expand Down