仅为某些资源覆盖ActiveAdmin资源控制器

时间:2017-05-16 18:30:40

标签: ruby-on-rails override activeadmin

在我的应用程序中,一些资源需要符合hippa标准,我们会根据需要做一些事情 - 使用ActiveAdmin :: Comments作为一种git评论系统,如果没有过滤则隐藏索引集合应用等

所有的hippa资源都是在正常的ActiveAdmin.register [资源]中编写的 - 所以我不希望多次剪切和粘贴代码到每个资源,我希望有一种方法可以覆盖基础资源控制器在其他地方,然后从HippaResource而不是基地拉这些特定资源?或者有没有办法扩展或包含使用的通用代码?

1 个答案:

答案 0 :(得分:0)

好吧,我将再一次回答我自己的问题 - 虽然说实话,即使我已经明白了,但我确定必须有一个更简单的方法它

基本上我在config / initializers / active_admin.rb中编写了我想要的覆盖 - 这通常会覆盖已经存在的资源控制器,但这不是我想要的 - 我想一些 hippa commpliant resource / resource_controllers以某种方式操作 - 隐藏数据的任何索引页面,仅在过滤后显示。

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

当使用ActiveAdmin.dialog单击“删除”链接或按钮时,我甚至可以执行删除/弹出对话框以输入注释。如果你看一下,我将 delete_link 类更改为 hippa_delete_link 类,这个类将被这个额外的javascript选中:

(function() {
  $(document).on('ready page:load turbolinks:load', function() {
    $('.hippa_delete_link').click(function(e) {
      var message;
      e.stopPropagation();
      e.preventDefault();
      if (message = $(this).data('confirm')) {
        return ActiveAdmin.modal_dialog(message, $(this).data('inputs'), (function(_this) {
          return function(inputs) {
            return $(_this).trigger('confirm:complete', inputs);
          };
        })(this));
      } else {
        return $(this).trigger('confirm:complete');
      }
    });
    $('.hippa_delete_link').on('confirm:complete', function(e, inputs) {

        var url = this.href;

        $.ajax({
            data: inputs,
            url: url,
            type: "DELETE"
        });
    });
  });

}).call(this);

这样做是将{comment:“Text input”}哈希传递给delete方法。