From 403f4b5fcc71986d14e2d3e9cda865959602412e Mon Sep 17 00:00:00 2001 From: Shouichi Kamiya Date: Thu, 25 Apr 2024 20:31:09 +0900 Subject: [PATCH] Support custom fields without corresponding model attributes The current implementation assumes fields have corresponding model attributes. But sometimes, we just want to display a button or a link that is not backed by an attribute. This change simply relaxes the assumption and allows custom fields that are not tied to model attributes. --- lib/administrate/page/base.rb | 2 +- spec/example_app/app/dashboards/customer_dashboard.rb | 3 ++- spec/example_app/app/fields/non_attribute_field.rb | 5 +++++ .../app/views/fields/non_attribute_field/_form.html.erb | 1 + .../app/views/fields/non_attribute_field/_index.html.erb | 1 + .../app/views/fields/non_attribute_field/_show.html.erb | 1 + spec/features/show_page_spec.rb | 8 ++++++++ 7 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 spec/example_app/app/fields/non_attribute_field.rb create mode 100644 spec/example_app/app/views/fields/non_attribute_field/_form.html.erb create mode 100644 spec/example_app/app/views/fields/non_attribute_field/_index.html.erb create mode 100644 spec/example_app/app/views/fields/non_attribute_field/_show.html.erb diff --git a/lib/administrate/page/base.rb b/lib/administrate/page/base.rb index 78fbf1a6bd..58c87068e9 100644 --- a/lib/administrate/page/base.rb +++ b/lib/administrate/page/base.rb @@ -36,7 +36,7 @@ def attribute_field(dashboard, resource, attribute_name, page) end def get_attribute_value(resource, attribute_name) - resource.public_send(attribute_name) + resource.try(attribute_name) end attr_reader :dashboard, :options diff --git a/spec/example_app/app/dashboards/customer_dashboard.rb b/spec/example_app/app/dashboards/customer_dashboard.rb index 79786fa4f7..910600c363 100644 --- a/spec/example_app/app/dashboards/customer_dashboard.rb +++ b/spec/example_app/app/dashboards/customer_dashboard.rb @@ -17,7 +17,8 @@ class CustomerDashboard < Administrate::BaseDashboard searchable_fields: ["name"], include_blank: true ), - password: Field::Password + password: Field::Password, + non_attribute_field: NonAttributeField } COLLECTION_ATTRIBUTES = ATTRIBUTE_TYPES.keys - %i[created_at updated_at] diff --git a/spec/example_app/app/fields/non_attribute_field.rb b/spec/example_app/app/fields/non_attribute_field.rb new file mode 100644 index 0000000000..dc76e09579 --- /dev/null +++ b/spec/example_app/app/fields/non_attribute_field.rb @@ -0,0 +1,5 @@ +class NonAttributeField < Administrate::Field::Base + def to_s + "Hello, Non Attribute Field" + end +end diff --git a/spec/example_app/app/views/fields/non_attribute_field/_form.html.erb b/spec/example_app/app/views/fields/non_attribute_field/_form.html.erb new file mode 100644 index 0000000000..b1c159f3b5 --- /dev/null +++ b/spec/example_app/app/views/fields/non_attribute_field/_form.html.erb @@ -0,0 +1 @@ +

NonAttributeField is not supposed to be used in form.

diff --git a/spec/example_app/app/views/fields/non_attribute_field/_index.html.erb b/spec/example_app/app/views/fields/non_attribute_field/_index.html.erb new file mode 100644 index 0000000000..6d9dbc9070 --- /dev/null +++ b/spec/example_app/app/views/fields/non_attribute_field/_index.html.erb @@ -0,0 +1 @@ +<%= field.to_s %> diff --git a/spec/example_app/app/views/fields/non_attribute_field/_show.html.erb b/spec/example_app/app/views/fields/non_attribute_field/_show.html.erb new file mode 100644 index 0000000000..6d9dbc9070 --- /dev/null +++ b/spec/example_app/app/views/fields/non_attribute_field/_show.html.erb @@ -0,0 +1 @@ +<%= field.to_s %> diff --git a/spec/features/show_page_spec.rb b/spec/features/show_page_spec.rb index 786d57f291..72eab95400 100644 --- a/spec/features/show_page_spec.rb +++ b/spec/features/show_page_spec.rb @@ -277,6 +277,14 @@ end end + it "displays non-attribute field" do + customer = create(:customer) + + visit admin_customer_path(customer) + + expect(page).to have_text("Hello, Non Attribute Field") + end + def ids_in_table all("tr td:first-child").map(&:text).map(&:to_i) end