Skip to content

Commit

Permalink
Add sort_by and direction option for HasMany field (thoughtbot#810)
Browse files Browse the repository at this point in the history
* Add `sort_by` and `direction` options to HasMany field
* Add spec for `sort_by` and `direction` in HasMany field
* [Docs] Add instructions for HasMany sort_by and direction options
  • Loading branch information
klaseskilson authored and iarie committed Jun 17, 2017
1 parent 2a2d024 commit 1f3b0c4
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 8 deletions.
4 changes: 4 additions & 0 deletions docs/customizing_dashboards.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ which are specified through the `.with_options` class method:
`:limit` - Set the number of resources to display in the show view. Default is
`5`.

`:sort_by` - What to sort the association by in the show view.

`:direction` - What direction the sort should be in, `:asc` (default) or `:desc`.

**Field::Number**

`:decimals` - Set the number of decimals to display. Defaults to `0`.
Expand Down
15 changes: 14 additions & 1 deletion lib/administrate/field/has_many.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require_relative "associative"
require "administrate/page/collection"
require "administrate/order"

module Administrate
module Field
Expand Down Expand Up @@ -37,7 +38,7 @@ def permitted_attribute
end

def resources(page = 1)
data.page(page).per(limit)
order.apply(data).page(page).per(limit)
end

def more_than_limit?
Expand All @@ -58,6 +59,18 @@ def candidate_resources
def display_candidate_resource(resource)
associated_dashboard.display_resource(resource)
end

def order
@_order ||= Administrate::Order.new(sort_by, direction)
end

def sort_by
options[:sort_by]
end

def direction
options[:direction]
end
end
end
end
12 changes: 11 additions & 1 deletion spec/factories.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@
factory :customer do
sequence(:name) { |n| "Customer #{n}" }
email { name.downcase.gsub(" ", "_") + "@example.com" }

transient do
order_count 3
end

trait :with_orders do
after(:create) do |customer, evaluator|
create_list(:order, evaluator.order_count, customer: customer)
end
end
end

factory :line_item do
Expand All @@ -14,7 +24,7 @@
factory :order do
customer
address_line_one "85 2nd St"
address_line_two "#700"
sequence(:address_line_two) { |n| "#700 (#{n})" }
address_city "San Francisco"
address_state "CA"
address_zip "94110"
Expand Down
48 changes: 42 additions & 6 deletions spec/lib/fields/has_many_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -106,22 +106,58 @@
describe "#resources" do
it "limits the number of records shown" do
limit = Administrate::Field::HasMany::DEFAULT_LIMIT
resources = MockRelation.new([:a] * (limit + 1))
customer = FactoryGirl.create(:customer, :with_orders, order_count: 10)
resources = customer.orders

association = Administrate::Field::HasMany
field = association.new(:customers, resources, :show)
field = association.new(:orders, resources, :show)

expect(field.resources).to eq([:a] * limit)
expect(field.resources.size).to eq(limit)
end

context "with `limit` option" do
it "limits the number of items returned" do
resources = MockRelation.new([:a, :b, :c])
customer = FactoryGirl.create(:customer, :with_orders)
resources = customer.orders

association = Administrate::Field::HasMany.with_options(limit: 1)
field = association.new(:customers, resources, :show)
field = association.new(:orders, resources, :show)

expect(field.resources).to be_one
end
end

context "with `sort_by` option" do
it "returns the resources in correct order" do
customer = FactoryGirl.create(:customer, :with_orders)
options = { sort_by: :address_line_two }
association = Administrate::Field::HasMany.with_options(options)
field = association.new(:orders, customer.orders, :show)

correct_order = customer.orders.sort_by(&:address_line_two).map(&:id)
reversed_order = customer.orders.sort do |a, b|
b.address_line_two <=> a.address_line_two
end

expect(field.resources.map(&:id)).to eq correct_order
expect(field.resources.map(&:id)).to_not eq reversed_order.map(&:id)
end
end

context "with `direction` option" do
it "returns the resources in correct order" do
customer = FactoryGirl.create(:customer, :with_orders)
options = { sort_by: :address_line_two, direction: :desc }
association = Administrate::Field::HasMany.with_options(options)
field = association.new(:orders, customer.orders, :show)

reversed_order = customer.orders.sort_by(&:address_line_two).map(&:id)
correct_order = customer.orders.sort do |a, b|
b.address_line_two <=> a.address_line_two
end

expect(field.resources).to eq([:a])
expect(field.resources.map(&:id)).to eq correct_order.map(&:id)
expect(field.resources.map(&:id)).to_not eq reversed_order
end
end
end
Expand Down

0 comments on commit 1f3b0c4

Please sign in to comment.