问题描述
在我的应用程序中,一些资源需要符合hippa规范,并且我们会做一些符合此需求的事情-使用ActiveAdmin :: Comments作为一种git注释系统,并在没有过滤的情况下隐藏索引集合已应用等.
In my app, some of the resources need to be hippa compliant and we do some things to fit in with that need - using ActiveAdmin::Comments as a sort of git commenting system, and hiding the index collection if there's no filtering applied, etc.
所有的河马资源都完全以普通的ActiveAdmin.register [资源]形式编写,因此,我希望有一种方法可以覆盖基本资源,而不是将代码多次剪切并粘贴到每个资源上.控制器,然后将这些特定资源从HippaResource而不是基础资源中提取出来?还是有一种方法可以扩展或包括所使用的通用代码?
All the hippa resources are written totally generically within the normal ActiveAdmin.register [resource] -- so rather than cutting and pasting the code multiple times to every resource, I was hoping there was a way for me to override the base resource controller elsewhere and then have these specific resources pull from the HippaResource rather than the base? Or is there a way to extend or include the generic code used?
推荐答案
好吧,我将再次回答自己的问题-坦白地说,即使我弄清楚了",我也是确定必须有一种更简单的方法.
Well, once again I'm going to answer my own question - though to be honest, even though I 'figured it out', I'm sure there must be an easier way to do it.
基本上,我在config/initializers/active_admin.rb中编写了我想要的覆盖-通常会覆盖已经存在的资源控制器,但这不是我想要的-我想要 some hippa举足轻重的resource/resource_controllers以某些方式起作用-隐藏数据的任何索引页,仅在过滤后显示.
Basically I wrote the overriding I wanted within the config/initializers/active_admin.rb -- which would normally override already existing resource controllers, but that wasn't what I wanted - I wanted some hippa commpliant resource / resource_controllers to act in certain ways - to hide any index page of data and only display after being filtered.
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提取:
I was even able to do the delete / popup dialog box to enter in a comment when the 'delete' link or button was clicked by using the ActiveAdmin.dialog. If you look above I changed the delete_link class to a hippa_delete_link class which would be picked up by this additional 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);
这是通过{注释:文本输入"}哈希传递到delete方法.
What this does is pass along a {comment: "Text input"} hash to the delete method.
这篇关于仅对某些资源覆盖ActiveAdmin资源控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!