diff --git a/docs/customizing_dashboards.md b/docs/customizing_dashboards.md index 6d4d839d49..052f38f5f3 100644 --- a/docs/customizing_dashboards.md +++ b/docs/customizing_dashboards.md @@ -82,7 +82,8 @@ the table views and in the dropdown menu on the record forms. You can set multiple columns as well with direction. E.g.: `"name, email DESC"`. `:scope` - Specifies a custom scope inside a callable. Useful for preloading. -Example: `.with_options(scope: -> { MyModel.includes(:rel).limit(5) })` +Example #1: `.with_options(scope: -> { MyModel.includes(:rel).limit(5) })` +Example #2: `.with_options(scope: -> (field) { field.resource.my_models.includes(:rel).limit(5) })` `:include_blank` - Specifies if the select element to be rendered should include blank option. Default is `true`. @@ -113,7 +114,7 @@ association `belongs_to :country`, from your model. **Field::HasMany** -`:collection_attributes` - Set the columns to display in the show view. +`:collection_attributes` - Set the columns to display in the show view. Default is COLLECTION_ATTRIBUTES in dashboard. `:limit` - The number of resources (paginated) to display in the show view. To disable pagination, diff --git a/lib/administrate/field/belongs_to.rb b/lib/administrate/field/belongs_to.rb index c26a5affec..aad72718d8 100644 --- a/lib/administrate/field/belongs_to.rb +++ b/lib/administrate/field/belongs_to.rb @@ -41,7 +41,12 @@ def include_blank_option private def candidate_resources - scope = options[:scope] ? options[:scope].call : associated_class.all + scope = + if options[:scope] + options[:scope].arity.positive? ? options[:scope].call(self) : options[:scope].call + else + associated_class.all + end order = options.delete(:order) order ? scope.reorder(order) : scope diff --git a/spec/lib/fields/belongs_to_spec.rb b/spec/lib/fields/belongs_to_spec.rb index 4ae0b1b8d9..8fef616191 100644 --- a/spec/lib/fields/belongs_to_spec.rb +++ b/spec/lib/fields/belongs_to_spec.rb @@ -306,6 +306,23 @@ expect(resources).to eq ["customer-3", "customer-2"] end + + context "when scope with argument" 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::BelongsTo.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 end