Skip to content

Commit

Permalink
Add call-able :scope option to Field::HasMany
Browse files Browse the repository at this point in the history
  • Loading branch information
goosys committed Oct 30, 2024
1 parent 0aeed31 commit 17c02ae
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 6 deletions.
11 changes: 5 additions & 6 deletions lib/administrate/field/has_many.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,11 @@ def includes
end

def candidate_resources
if options.key?(:includes)
includes = options.fetch(:includes)
associated_class.includes(*includes).all
else
associated_class.all
end
scope = options[:scope] ? options[:scope].call(self) : associated_class.all
scope = scope.includes(*options.fetch(:includes)) if options.key?(:includes)

order = options.delete(:order)
order ? scope.reorder(order) : scope
end

def display_candidate_resource(resource)
Expand Down
52 changes: 52 additions & 0 deletions spec/lib/fields/has_many_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -299,4 +299,56 @@
end
end
end

describe "#associated_resource_options" do
context "with `order` option" do
it "returns the resources in correct order" do
order = create(:order)
create_list(:customer, 5)
options = {order: "name"}
association = Administrate::Field::HasMany.with_options(options)

field = association.new(:customer, [], :show, resource: order)

correct_order = Customer.order("name").pluck(:id)

resources = field.associated_resource_options.compact.to_h.values
expect(resources).to eq correct_order
end

it "ignores the order passed in `scope`" do
order = create(:order)
create_list(:customer, 3)
options = {
order: "name",
scope: ->(_field) { Customer.order(name: :desc) }
}
association = Administrate::Field::HasMany.with_options(options)

field = association.new(:customer, [], :show, resource: order)

correct_order = Customer.order("name").pluck(:id)

resources = field.associated_resource_options.compact.to_h.values
expect(resources).to eq correct_order
end
end

context "with `scope` option" do
it "returns the resources within the passed scope" do
# Building instead of creating, to avoid a dependent customer being
# created, leading to random failures
order = build(:order)

1.upto(3) { |i| create :customer, name: "customer-#{i}" }
scope = ->(_field) { Customer.order(name: :desc).limit(2) }

association = Administrate::Field::HasMany.with_options(scope: scope)
field = association.new(:customer, [], :show, resource: order)
resources = field.associated_resource_options.compact.to_h.keys

expect(resources).to eq ["customer-3", "customer-2"]
end
end
end
end

0 comments on commit 17c02ae

Please sign in to comment.