I am displaying a table with ActiveAdmin using the "Index as Table" functionality:
index :pagination_total => false do
if Ability.new(current_user).can? :manage, :metric
selectable_column
end
column '' do |metric|
links = link_to(metric.icon, admin_metric_path(metric), :title => metric.comment)
links += link_to(metric.data_icon, admin_metric_path(metric)) unless metric.datum_ids.empty?
links
end
column 'Status', :success, sortable: :success do |metric|
metric.success == 1 ? status_tag('Success', :ok) : status_tag('FAILED', :error)
end
column 'When (UTC)', :createddttm
column 'What', :metric_name
column 'Area', :logarea
column 'Subarea', :subarea
column 'Value', :value
column 'Machine', :machine_name, sortable: 'machinename.machinename'
column 'Domain', :domain_name, sortable: 'domain.domainname'
column 'Product', :product_name, sortable: 'product.productname'
column 'Version', :product_version, sortable: 'product.productversion'
column 'Install Type', :install_type, sortable: 'product.productinstalltype'
column 'Lang', :language
column 'Duration', :duration
end
Given that the row data does not change, I would like to add row level caching of the rendered html with a long expiry time but I can't figure out how to hook into the row rendering code in Arbre.
I am currently caching the entire page for 60 seconds but that is not optimal. My cache store is Dalli / memcached.
UPDATE 2:
Try this with the cashed_rows
method:
# lib\active_admin\views\index_as_table.rb
module ActiveAdmin
module Views
class IndexAsTable < ActiveAdmin::Component
def build(page_presenter, collection)
table_options = {
id: "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 = table_for collection, table_options do |t|
table_config_block = page_presenter.block || default_table
instance_exec(t, &table_config_block)
end
#new code
rows = []
table.children.each {|row| rows << row.to_s}
resource_class.cached_rows = rows
table
end
end
end
end
UPDATE:
This is a monkey patch. Create a new file in lib folder, then you can use the rows
array.
module ActiveAdmin
module Views
class TableFor < Arbre::HTML::Table
def build_table_body
@tbody = tbody do
# Build enough rows for our collection
@collection.each do |elem|
classes = [cycle('odd', 'even')]
if @row_class
classes << @row_class.call(elem)
end
tr(class: classes.flatten.join(' '), id: dom_id_for(elem))
end
end
#new code: rows will contain the html string for each row
rows = []
@tbody.children.each {|row| rows << row.to_s} #you can also use: @tbody.to_s
YourActiveRecordModel.cached_rows= rows
@tbody
end
end
end
end
class YourActiveRecordModel < ActiveRecord::Base
def self.cached_rows=(attr)
@@rows = attr
end
def self.cached_rows
@@rows
end
end
Now you can get the html string: YourActiveRecordModel.cached_rows if you build the index table at least once.
Old answer:
I would make a new table that contains the string representation of the contained objects. You can determine which record want to load (the original or the cached record):
controller do
def find_resource
if params[:action] == 'index' #or something similar
CachedRecords.find(params[:id])
elsif params[:action] == 'edit'
OriginalRecords.find(params[:id])
end
end