Ruby on rails 仅覆盖某些资源的ActiveAdmin资源控制器

Ruby on rails 仅覆盖某些资源的ActiveAdmin资源控制器,ruby-on-rails,overriding,activeadmin,Ruby On Rails,Overriding,Activeadmin,在我的应用程序中,一些资源需要符合hippa,我们做了一些事情来满足这一需求——使用ActiveAdmin::Comments作为一种git注释系统,如果没有应用过滤,则隐藏索引集合,等等 所有hippa资源都是在普通的ActiveAdmin.register[resource]中完全通用地编写的——因此,与其将代码多次剪切和粘贴到每个资源,我希望有一种方法可以覆盖其他地方的基本资源控制器,然后让这些特定的资源从HippaResource而不是从基本资源中提取?或者有没有一种方法可以扩展或包含所

在我的应用程序中,一些资源需要符合hippa,我们做了一些事情来满足这一需求——使用ActiveAdmin::Comments作为一种git注释系统,如果没有应用过滤,则隐藏索引集合,等等


所有hippa资源都是在普通的ActiveAdmin.register[resource]中完全通用地编写的——因此,与其将代码多次剪切和粘贴到每个资源,我希望有一种方法可以覆盖其他地方的基本资源控制器,然后让这些特定的资源从HippaResource而不是从基本资源中提取?或者有没有一种方法可以扩展或包含所使用的通用代码?

好吧,我要再次回答我自己的问题——尽管说实话,即使我“弄明白了”,我相信一定有一种更简单的方法可以做到这一点

基本上,我在config/initializers/active_admin.rb中编写了我想要的重写——这通常会重写现有的资源控制器,但这并不是我想要的——我想要一些符合hippa的资源/资源控制器以某种方式工作——隐藏任何数据索引页,并且只在过滤后显示

module ActiveAdmin
  module Views
    class IndexAsHippa < ActiveAdmin::Component

      def build(page_presenter, collection)
        table_options = {
          id: "hippa_index_table_#{active_admin_config.resource_name.plural}",
          sortable: true,
          class: "index_table index",
          i18n: active_admin_config.resource_class,
          paginator: page_presenter[:paginator] != false,
          row_class: page_presenter[:row_class]
        }


        table_for collection, table_options do |t|
          table_config_block = page_presenter.block || default_table
          instance_exec(t, &table_config_block)
        end
      end

      def table_for(*args, &block)
        insert_tag IndexTableFor, *args, &block
      end

      def default_table
        proc do
          selectable_column
          id_column if resource_class.primary_key
          active_admin_config.resource_columns.each do |attribute|
            column attribute
          end
          actions
        end
      end

      def self.index_name
        "hippa_table"
      end

      #
      # Extend the default ActiveAdmin::Views::TableFor with some
      # methods for quickly displaying items on the index page
      #
      class IndexTableFor < ::ActiveAdmin::Views::TableFor

        # Display a column for checkbox
        def selectable_column
          return unless active_admin_config.batch_actions.any?
          column resource_selection_toggle_cell, class: 'col-selectable', sortable: false do |resource|
            resource_selection_cell resource
          end
        end

        def index_column(start_value = 1)
          column '#', class: 'col-index', sortable: false do |resource|
            @collection.offset_value + @collection.index(resource) + start_value
          end
        end

        # Display a column for the id
        def id_column
          raise "#{resource_class.name} has no primary_key!" unless resource_class.primary_key
          column(resource_class.human_attribute_name(resource_class.primary_key), sortable: resource_class.primary_key) do |resource|
            if controller.action_methods.include?('show')
              link_to resource.id, resource_path(resource), class: "resource_id_link"
            elsif controller.action_methods.include?('edit')
              link_to resource.id, edit_resource_path(resource), class: "resource_id_link"
            else
              resource.id
            end
          end
        end


        def actions(options = {}, &block)
          name          = options.delete(:name)     { '' }
          defaults      = options.delete(:defaults) { true }
          dropdown      = options.delete(:dropdown) { false }
          dropdown_name = options.delete(:dropdown_name) { I18n.t 'active_admin.dropdown_actions.button_label', default: 'Actions' }

          options[:class] ||= 'col-actions'

          column name, options do |resource|
            if dropdown
              dropdown_menu dropdown_name do
                defaults(resource) if defaults
                instance_exec(resource, &block) if block_given?
              end
            else
              table_actions do
                defaults(resource, css_class: :member_link) if defaults
                if block_given?
                  block_result = instance_exec(resource, &block)
                  text_node block_result unless block_result.is_a? Arbre::Element
                end
              end
            end
          end
        end

      private

        def defaults(resource, options = {})
          if controller.action_methods.include?('show') && authorized?(ActiveAdmin::Auth::READ, resource)
            item I18n.t('active_admin.view'), resource_path(resource), class: "view_link #{options[:css_class]}", title: I18n.t('active_admin.view')
          end
          if controller.action_methods.include?('edit') && authorized?(ActiveAdmin::Auth::UPDATE, resource)
            item I18n.t('active_admin.edit'), edit_resource_path(resource), class: "edit_link #{options[:css_class]}", title: I18n.t('active_admin.edit')
          end
          if controller.action_methods.include?('destroy') && authorized?(ActiveAdmin::Auth::DESTROY, resource)
            item I18n.t('active_admin.delete'), resource_path(resource), class: "hippa_delete_link  #{options[:css_class]}", title: I18n.t('active_admin.delete'),
              method: :delete, data: {confirm: "Reason for deletion?", inputs: {comment:  :textarea}}
          end
        end

        class TableActions < ActiveAdmin::Component
          builder_method :table_actions

          def item *args
            text_node link_to *args
          end
        end
      end # IndexTableFor

    end # IndexAsTable
  end
end


##  custom blank slate
class HippaBlankSlate < ActiveAdmin::Component
  builder_method :blank_slate

  def default_class_name
    'blank_slate_container'
  end

  def build(content)
    super(span("You must first filter this resource to view.", class: "blank_slate"))
  end
end


HIPPA_CLASS_ARRAY = %w( DailySummary Doctor Parent Patient PrescribedTension Prescription Product Sensor SensorEvent Treatment )

## resource overrid
class ActiveAdmin::Resource
  module ActionItems
    def initialize(*args)
        super
        add_default_action_items
    end

    def add_default_show_action_item
      if HIPPA_CLASS_ARRAY.include? resource_class.name
        add_action_item :destroy, only: [:show, :edit] do
          if controller.action_methods.include?('destroy') && authorized?(ActiveAdmin::Auth::DESTROY, resource)
            localizer = ActiveAdmin::Localizers.resource(active_admin_config)
            link_to localizer.t(:delete_model), resource_path(resource), class: "hippa_delete_link",  method: :delete,
              data: {confirm: "Reason for deletion?", inputs: {comment:  :textarea}}
          end
        end
      else
        add_action_item :destroy, only: [:show, :edit] do
          if controller.action_methods.include?('destroy') && authorized?(ActiveAdmin::Auth::DESTROY, resource)
            localizer = ActiveAdmin::Localizers.resource(active_admin_config)
            link_to localizer.t(:delete_model), resource_path(resource), method: :delete,
              data: {confirm: localizer.t(:delete_confirmation)}
          end
        end
      end
    end

  end
end











##  resource controller overrides

class ActiveAdmin::ResourceController
  include InheritedResources::DSL


    def apply_filtering(chain)
      if params['q'].blank?  && (HIPPA_CLASS_ARRAY.include? self.resource_class.name)
        @search = chain.ransack({})
        chain.none
      else
        super
      end 
    end



    def setup_comments
      klassname = self.resource_class.name.underscore
      if params[klassname][:comments_attributes]['0']['body'].blank?
        err = "A comment must be added to #{params[:action]} this #{klassname}."
      else
        params[klassname][:comments_attributes]['0']['namespace'] = 'admin'
        params[klassname][:comments_attributes]['0']['author_id'] = current_admin_user.id
        params[klassname][:comments_attributes]['0']['author_type'] = 'AdminUser'
      end
      if !err.nil?
        params[:error] = err
      end
      return 
    end


    def update(options={}, &block)
      if HIPPA_CLASS_ARRAY.include? self.resource_class.name
        setup_comments
        # save resource
        if params[:error].nil?
          super
          if resource.errors.any?
            params[:error] = resource.errors.full_messages.first
          end
        end
        # see if any error messages
        if !params[:error].nil?
          redirect_to({ action: 'edit' }, alert: params[:error])
        end

      else
        super
      end
    end


    def create
      if HIPPA_CLASS_ARRAY.include? self.resource_class.name
        setup_comments
        if params[:error].nil?
          resource = self.resource_class.new(permitted_params[self.resource_class.name.underscore.to_sym])
          @comment=ActiveAdmin::Comment.new(permitted_params[self.resource_class.name.underscore.to_sym][:comments_attributes]['0'])
          @comment.resource = resource
          resource.comments.first.resource = resource

          if resource.valid?
            resource.save
          else
            if resource.errors.any?
              params[:error] = resource.errors.full_messages.first
              end
          end
        end


        if !params[:error].nil?
          redirect_to({ action: 'index' }, alert: params[:error])
        else
          redirect_to({ action: 'index' }, alert: "#{resource_class} was successfully saved with comment.")
        end
      else
        super
      end
    end

    def destroy
      if HIPPA_CLASS_ARRAY.include? self.resource_class.name
        if !params[:comment].nil? && !params[:comment].empty?
          @comment=ActiveAdmin::Comment.new(namespace: "admin", author: current_admin_user, resource: resource, body: params[:comment]  )
          @comment.save

          resource.destroy

          redirect_to({ action: 'index' }, notice: "Delete was successful.");
        else
           flash[:notice] = "A delete comment can not be blank."
            render :js => 'window.location.reload()'
        end
      else
        super
      end
    end
    end

这样做的目的是将一个{comment:“Text input”}散列传递给delete方法。

好吧,我将再次回答我自己的问题-尽管说实话,即使我“弄明白了”,我相信一定有更简单的方法来做

基本上,我在config/initializers/active_admin.rb中编写了我想要的重写——这通常会重写现有的资源控制器,但这并不是我想要的——我想要一些符合hippa的资源/资源控制器以某种方式工作——隐藏任何数据索引页,并且只在过滤后显示

module ActiveAdmin
  module Views
    class IndexAsHippa < ActiveAdmin::Component

      def build(page_presenter, collection)
        table_options = {
          id: "hippa_index_table_#{active_admin_config.resource_name.plural}",
          sortable: true,
          class: "index_table index",
          i18n: active_admin_config.resource_class,
          paginator: page_presenter[:paginator] != false,
          row_class: page_presenter[:row_class]
        }


        table_for collection, table_options do |t|
          table_config_block = page_presenter.block || default_table
          instance_exec(t, &table_config_block)
        end
      end

      def table_for(*args, &block)
        insert_tag IndexTableFor, *args, &block
      end

      def default_table
        proc do
          selectable_column
          id_column if resource_class.primary_key
          active_admin_config.resource_columns.each do |attribute|
            column attribute
          end
          actions
        end
      end

      def self.index_name
        "hippa_table"
      end

      #
      # Extend the default ActiveAdmin::Views::TableFor with some
      # methods for quickly displaying items on the index page
      #
      class IndexTableFor < ::ActiveAdmin::Views::TableFor

        # Display a column for checkbox
        def selectable_column
          return unless active_admin_config.batch_actions.any?
          column resource_selection_toggle_cell, class: 'col-selectable', sortable: false do |resource|
            resource_selection_cell resource
          end
        end

        def index_column(start_value = 1)
          column '#', class: 'col-index', sortable: false do |resource|
            @collection.offset_value + @collection.index(resource) + start_value
          end
        end

        # Display a column for the id
        def id_column
          raise "#{resource_class.name} has no primary_key!" unless resource_class.primary_key
          column(resource_class.human_attribute_name(resource_class.primary_key), sortable: resource_class.primary_key) do |resource|
            if controller.action_methods.include?('show')
              link_to resource.id, resource_path(resource), class: "resource_id_link"
            elsif controller.action_methods.include?('edit')
              link_to resource.id, edit_resource_path(resource), class: "resource_id_link"
            else
              resource.id
            end
          end
        end


        def actions(options = {}, &block)
          name          = options.delete(:name)     { '' }
          defaults      = options.delete(:defaults) { true }
          dropdown      = options.delete(:dropdown) { false }
          dropdown_name = options.delete(:dropdown_name) { I18n.t 'active_admin.dropdown_actions.button_label', default: 'Actions' }

          options[:class] ||= 'col-actions'

          column name, options do |resource|
            if dropdown
              dropdown_menu dropdown_name do
                defaults(resource) if defaults
                instance_exec(resource, &block) if block_given?
              end
            else
              table_actions do
                defaults(resource, css_class: :member_link) if defaults
                if block_given?
                  block_result = instance_exec(resource, &block)
                  text_node block_result unless block_result.is_a? Arbre::Element
                end
              end
            end
          end
        end

      private

        def defaults(resource, options = {})
          if controller.action_methods.include?('show') && authorized?(ActiveAdmin::Auth::READ, resource)
            item I18n.t('active_admin.view'), resource_path(resource), class: "view_link #{options[:css_class]}", title: I18n.t('active_admin.view')
          end
          if controller.action_methods.include?('edit') && authorized?(ActiveAdmin::Auth::UPDATE, resource)
            item I18n.t('active_admin.edit'), edit_resource_path(resource), class: "edit_link #{options[:css_class]}", title: I18n.t('active_admin.edit')
          end
          if controller.action_methods.include?('destroy') && authorized?(ActiveAdmin::Auth::DESTROY, resource)
            item I18n.t('active_admin.delete'), resource_path(resource), class: "hippa_delete_link  #{options[:css_class]}", title: I18n.t('active_admin.delete'),
              method: :delete, data: {confirm: "Reason for deletion?", inputs: {comment:  :textarea}}
          end
        end

        class TableActions < ActiveAdmin::Component
          builder_method :table_actions

          def item *args
            text_node link_to *args
          end
        end
      end # IndexTableFor

    end # IndexAsTable
  end
end


##  custom blank slate
class HippaBlankSlate < ActiveAdmin::Component
  builder_method :blank_slate

  def default_class_name
    'blank_slate_container'
  end

  def build(content)
    super(span("You must first filter this resource to view.", class: "blank_slate"))
  end
end


HIPPA_CLASS_ARRAY = %w( DailySummary Doctor Parent Patient PrescribedTension Prescription Product Sensor SensorEvent Treatment )

## resource overrid
class ActiveAdmin::Resource
  module ActionItems
    def initialize(*args)
        super
        add_default_action_items
    end

    def add_default_show_action_item
      if HIPPA_CLASS_ARRAY.include? resource_class.name
        add_action_item :destroy, only: [:show, :edit] do
          if controller.action_methods.include?('destroy') && authorized?(ActiveAdmin::Auth::DESTROY, resource)
            localizer = ActiveAdmin::Localizers.resource(active_admin_config)
            link_to localizer.t(:delete_model), resource_path(resource), class: "hippa_delete_link",  method: :delete,
              data: {confirm: "Reason for deletion?", inputs: {comment:  :textarea}}
          end
        end
      else
        add_action_item :destroy, only: [:show, :edit] do
          if controller.action_methods.include?('destroy') && authorized?(ActiveAdmin::Auth::DESTROY, resource)
            localizer = ActiveAdmin::Localizers.resource(active_admin_config)
            link_to localizer.t(:delete_model), resource_path(resource), method: :delete,
              data: {confirm: localizer.t(:delete_confirmation)}
          end
        end
      end
    end

  end
end











##  resource controller overrides

class ActiveAdmin::ResourceController
  include InheritedResources::DSL


    def apply_filtering(chain)
      if params['q'].blank?  && (HIPPA_CLASS_ARRAY.include? self.resource_class.name)
        @search = chain.ransack({})
        chain.none
      else
        super
      end 
    end



    def setup_comments
      klassname = self.resource_class.name.underscore
      if params[klassname][:comments_attributes]['0']['body'].blank?
        err = "A comment must be added to #{params[:action]} this #{klassname}."
      else
        params[klassname][:comments_attributes]['0']['namespace'] = 'admin'
        params[klassname][:comments_attributes]['0']['author_id'] = current_admin_user.id
        params[klassname][:comments_attributes]['0']['author_type'] = 'AdminUser'
      end
      if !err.nil?
        params[:error] = err
      end
      return 
    end


    def update(options={}, &block)
      if HIPPA_CLASS_ARRAY.include? self.resource_class.name
        setup_comments
        # save resource
        if params[:error].nil?
          super
          if resource.errors.any?
            params[:error] = resource.errors.full_messages.first
          end
        end
        # see if any error messages
        if !params[:error].nil?
          redirect_to({ action: 'edit' }, alert: params[:error])
        end

      else
        super
      end
    end


    def create
      if HIPPA_CLASS_ARRAY.include? self.resource_class.name
        setup_comments
        if params[:error].nil?
          resource = self.resource_class.new(permitted_params[self.resource_class.name.underscore.to_sym])
          @comment=ActiveAdmin::Comment.new(permitted_params[self.resource_class.name.underscore.to_sym][:comments_attributes]['0'])
          @comment.resource = resource
          resource.comments.first.resource = resource

          if resource.valid?
            resource.save
          else
            if resource.errors.any?
              params[:error] = resource.errors.full_messages.first
              end
          end
        end


        if !params[:error].nil?
          redirect_to({ action: 'index' }, alert: params[:error])
        else
          redirect_to({ action: 'index' }, alert: "#{resource_class} was successfully saved with comment.")
        end
      else
        super
      end
    end

    def destroy
      if HIPPA_CLASS_ARRAY.include? self.resource_class.name
        if !params[:comment].nil? && !params[:comment].empty?
          @comment=ActiveAdmin::Comment.new(namespace: "admin", author: current_admin_user, resource: resource, body: params[:comment]  )
          @comment.save

          resource.destroy

          redirect_to({ action: 'index' }, notice: "Delete was successful.");
        else
           flash[:notice] = "A delete comment can not be blank."
            render :js => 'window.location.reload()'
        end
      else
        super
      end
    end
    end
这样做的目的是将{comment:“Text input”}散列传递给delete方法