diff --git a/lib/administrate/base_dashboard.rb b/lib/administrate/base_dashboard.rb index 2774b619cf..305cda2008 100644 --- a/lib/administrate/base_dashboard.rb +++ b/lib/administrate/base_dashboard.rb @@ -59,8 +59,6 @@ def display_resource(resource) end def association_includes - association_classes = [Field::HasMany, Field::HasOne, Field::BelongsTo] - collection_attributes.map do |key| field = self.class::ATTRIBUTE_TYPES[key] @@ -74,5 +72,11 @@ def association_includes def attribute_not_found_message(attr) "Attribute #{attr} could not be found in #{self.class}::ATTRIBUTE_TYPES" end + + def association_classes + @association_classes ||= + ObjectSpace.each_object(Class). + select { |klass| klass < Administrate::Field::Associative } + end end end diff --git a/spec/example_app/app/dashboards/customer_dashboard.rb b/spec/example_app/app/dashboards/customer_dashboard.rb index 1d5e608789..8ecef8c7a3 100644 --- a/spec/example_app/app/dashboards/customer_dashboard.rb +++ b/spec/example_app/app/dashboards/customer_dashboard.rb @@ -1,4 +1,5 @@ require "administrate/base_dashboard" +require "administrate/field/has_many_variant" class CustomerDashboard < Administrate::BaseDashboard ATTRIBUTE_TYPES = { @@ -8,7 +9,7 @@ class CustomerDashboard < Administrate::BaseDashboard lifetime_value: Field::Number.with_options(prefix: "$", decimals: 2), name: Field::String, orders: Field::HasMany.with_options(limit: 2, sort_by: :id), - log_entries: Field::HasMany.with_options(limit: 2, sort_by: :id), + log_entries: Field::HasManyVariant.with_options(limit: 2, sort_by: :id), updated_at: Field::DateTime, kind: Field::Select.with_options(collection: Customer::KINDS), country: Field::BelongsTo.with_options( diff --git a/spec/example_app/app/views/fields/has_many_variant/_form.html.erb b/spec/example_app/app/views/fields/has_many_variant/_form.html.erb new file mode 100644 index 0000000000..d977aae80c --- /dev/null +++ b/spec/example_app/app/views/fields/has_many_variant/_form.html.erb @@ -0,0 +1,13 @@ +<%# +Just a copy of the HasMany _form partial, here to test that +things won't break if the app adds new types of association fields +%> + +
+ <%= f.label field.attribute_key, field.attribute %> +
+
+ <%= f.select(field.attribute_key, nil, {}, multiple: true) do %> + <%= options_for_select(field.associated_resource_options, field.selected_options) %> + <% end %> +
diff --git a/spec/example_app/app/views/fields/has_many_variant/_index.html.erb b/spec/example_app/app/views/fields/has_many_variant/_index.html.erb new file mode 100644 index 0000000000..e131531a88 --- /dev/null +++ b/spec/example_app/app/views/fields/has_many_variant/_index.html.erb @@ -0,0 +1,6 @@ +<%# +Just a copy of the HasMany _index partial, here to test that +things won't break if the app adds new types of association fields +%> + +<%= pluralize(field.data.size, field.attribute.to_s.humanize.downcase.singularize) %> diff --git a/spec/example_app/app/views/fields/has_many_variant/_show.html.erb b/spec/example_app/app/views/fields/has_many_variant/_show.html.erb new file mode 100644 index 0000000000..1916db768d --- /dev/null +++ b/spec/example_app/app/views/fields/has_many_variant/_show.html.erb @@ -0,0 +1,23 @@ +<%# +Just a copy of the HasMany _show partial, here to test that +things won't break if the app adds new types of association fields +%> + +<% if field.resources.any? %> + <% order = field.order_from_params(params.fetch(field.name, {})) %> + <% page_number = params.fetch(field.name, {}).fetch(:page, nil) %> + <%= render( + "collection", + collection_presenter: field.associated_collection(order), + collection_field_name: field.name, + page: page, + resources: field.resources(page_number, order), + table_title: field.name, + ) %> + <% if field.more_than_limit? %> + <%= paginate field.resources(page_number), param_name: "#{field.name}[page]" %> + <% end %> + +<% else %> + <%= t("administrate.fields.has_many.none", default: "–") %> +<% end %> diff --git a/spec/example_app/lib/administrate/field/has_many_variant.rb b/spec/example_app/lib/administrate/field/has_many_variant.rb new file mode 100644 index 0000000000..cee4bc67b9 --- /dev/null +++ b/spec/example_app/lib/administrate/field/has_many_variant.rb @@ -0,0 +1,9 @@ +require "administrate/field/has_many" + +module Administrate + module Field + class HasManyVariant < HasMany + # Only here to test that this works out of the box + end + end +end diff --git a/spec/features/show_page_spec.rb b/spec/features/show_page_spec.rb index 7308f8c375..700d33df81 100644 --- a/spec/features/show_page_spec.rb +++ b/spec/features/show_page_spec.rb @@ -10,7 +10,7 @@ visit admin_customer_path(customer) - within(".attribute-data--has-many table[aria-labelledby=orders]") do + within(table_for_attribute(:orders)) do ids_in_page1 = ids_in_table expect(ids_in_page1.count).to eq 2 expect(order_ids).to include(*ids_in_page1) @@ -18,7 +18,7 @@ click_on("Next ›") - within(".attribute-data--has-many table[aria-labelledby=orders]") do + within(table_for_attribute(:orders)) do ids_in_page2 = ids_in_table expect(ids_in_page2.count).to eq 2 expect(order_ids).to include(*ids_in_page2) @@ -73,7 +73,7 @@ order_ids = orders.sort_by(&:id).map(&:id).reverse - within(".attribute-data--has-many table[aria-labelledby=orders]") do + within(table_for_attribute(:orders)) do expect(order_ids.first(2)).to eq(ids_in_table) end @@ -81,7 +81,7 @@ order: :id, direction: :desc, page: 2 }) - within(".attribute-data--has-many table[aria-labelledby=orders]") do + within(table_for_attribute(:orders)) do expect(order_ids.last(2)).to eq(ids_in_table) end end @@ -104,11 +104,11 @@ order_ids = orders.sort_by(&:id).map(&:id).reverse log_entry_ids = log_entries.sort_by(&:id).map(&:id) - within(".attribute-data--has-many table[aria-labelledby=orders]") do + within(table_for_attribute(:orders)) do expect(order_ids.first(2)).to eq(ids_in_table) end - within(".attribute-data--has-many table[aria-labelledby=log_entries]") do + within(table_for_attribute(:log_entries)) do expect(log_entry_ids.first(2)).to eq(ids_in_table) end @@ -121,11 +121,11 @@ }, ) - within(".attribute-data--has-many table[aria-labelledby=orders]") do + within(table_for_attribute(:orders)) do expect(order_ids.last(2)).to eq(ids_in_table) end - within(".attribute-data--has-many table[aria-labelledby=log_entries]") do + within(table_for_attribute(:log_entries)) do expect(log_entry_ids.first(2)).to eq(ids_in_table) end end @@ -211,4 +211,8 @@ def ids_in_table all("tr td:first-child").map(&:text).map(&:to_i) end + + def table_for_attribute(attr_name) + find("table[aria-labelledby=#{attr_name}]") + end end