Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • A administrate
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 96
    • Issues 96
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 32
    • Merge requests 32
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • thoughtbot, inc.
  • administrate
  • Issues
  • #1586
Closed
Open
Issue created Mar 26, 2020 by Pablo Brasero@pablobmContributor

Support for virtual fields (regression)

When https://github.com/thoughtbot/administrate/pull/920 was merged, it broke apps that depended on the old behaviour.

These are two reports on this issue:

Report by @wkirby in https://github.com/thoughtbot/administrate/pull/920#issuecomment-599722598

This PR appears to break any support for virtual fields by enforcing the the resource must define a method to respond to all keys in the Dashboard class. Maybe this is the desired behavior, but the following use case was possible in 0.12.0, and was very useful:

class ReportDashboard < Administrate::BaseDashboard
  ATTRIBUTE_TYPES = {
    id: Field::Number,
    filename: Field::String,
    mimetype: Field::String,
    s3_key: Field::String,
    download: S3DownloadField.with_options({ download_path: :download_lab_report_path }),
    page_count: Field::Number,
    created_at: Field::DateTime,
    updated_at: Field::DateTime
  }.freeze

  COLLECTION_ATTRIBUTES = [
    :id,
    :filename,
    :download,
    :mimetype,
    :created_at
  ].freeze

  SHOW_PAGE_ATTRIBUTES = [
    :id,
    :download,
    :filename,
    :mimetype,
    :s3_key,
    :page_count,
    :created_at,
    :updated_at
  ].freeze

  FORM_ATTRIBUTES = [
    :lab,
    :filename,
    :mimetype,
    :s3_key,
    :page_count
  ].freeze
end
class S3DownloadField < Administrate::Field::Base
  def to_s
    data
  end

  def downloadable?
    options.key?(:download_path)
  end

  def destroyable?
    options.key?(:destroy_path)
  end

  def destroy_path(field, attachment)
    path_helper(:destroy_path, field, attachment)
  end

  def download_path(field, attachment)
    path_helper(:download_path, field, attachment)
  end

  private

  def path_helper(key, field, _attachment)
    path_helper = options.fetch(key)
    Rails.application.routes.url_helpers.send(path_helper, field.resource)
  end
end

This allowed us to inject a download link for our S3 resource without editing the underlying views, or modifying the display for any of the actual attributes.

Is there any advice on how to fix this without defining useless methods on our models?

Report by @Timmitry in https://github.com/thoughtbot/administrate/issues/1570#issuecomment-600472047

We are having similar problems - updating to 0.13 breaks all of our virtual fields (and we have many of those). Since 0.13 fixes a CVE, this is kind of an urgent problem 😕

We fixed the issue temporarily by adding an initializer to config/initializers with the following code:

# Monkey patch to make the … page work again
# The breaking change was https://github.com/thoughtbot/administrate/commit/dc856a917aa67e998860bb42664b5da94eb0e682#diff-a4a632998186059ef606368d710ac173
# Issue is open at https://github.com/thoughtbot/administrate/issues/1570
raise "Try to remove this monkey patch when updating Administrate" if Gem.loaded_specs["administrate"].version != Gem::Version.new("0.13.0")

module Administrate
  module Page
    class Base
      protected

      def get_attribute_value(resource, attribute_name)
        resource.public_send(attribute_name)
      rescue NameError
        nil
      end
    end
  end
end
Assignee
Assign to
Time tracking