Replies: 13 comments
-
It is not possible at the moment. It could theoretically work with index do
cache "user" do
column :user
end
end But since a custom templating language (Abre) is being used, it doesn't work. The method |
Beta Was this translation helpful? Give feedback.
-
Here is a helper method I use to cache arbre output. It could probably be # application_helper.rb
# Caches Arbre output.
#
# context - ActiveAdmin instance context
# args - Arguments passed to Rails.cache calls.
#
# Yielding the first time adds to the output buffer regardless of the
# returned value. The missed cache must be handled carefully.
#
# Returns yielded Arbre on cache miss OR an HTML string wrapped in
# an Arbre div on cache hit.
def cache_arbre(context, *args)
if controller.perform_caching
if Rails.cache.exist?(*args)
context.instance_eval do
div(Rails.cache.read(*args))
end
else
Rails.cache.write(*args, yield.to_s)
end
else
yield
end
end Usage would be like the following: ActiveAdmin.register User do
show do
arbre_cache(self, user.cache_key) do
attributes_table do
row :name
row :email
row :expensive_calculation
end
end
end
end |
Beta Was this translation helpful? Give feedback.
-
Hi @zorab47, thanks for the tip! But trying it out, the module ApplicationHelper
def cache_arbre(*args)
if controller.perform_caching
opts = args.extract_options!.merge namespace: :arbre
Rails.cache.fetch(*args, opts) { yield.to_s }
else
yield
end
end
end I also updated it to use a namespace to prevent key collisions. |
Beta Was this translation helpful? Give feedback.
-
In my usage the cached content would only be displayed if it was wrapped in an Arbre element. The one exception is when the string is the last value in the block. As an example: show do
panel "Display Test" do
"Text which won't be rendered."
"Last string in block, which will be rendered."
end
end From what I've determined Arbre handles a block returning a string by automatically wrapping it in a So, If cached content is followed by more Arbre elements it won't be rendered. |
Beta Was this translation helpful? Give feedback.
-
@zorab47, I can confirm you're right , and cached Arbre blocks are empty in some cases. |
Beta Was this translation helpful? Give feedback.
-
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 with a long expiry time but I can't figure out how to hook into the row rendering code in Arbre. I'd love to see a way to cache each row. |
Beta Was this translation helpful? Give feedback.
-
Another thing to note with the above |
Beta Was this translation helpful? Give feedback.
-
If you want to use div, text_node or other arbre elements you could write the helper like this: def aa_cache(context, cache_key, &block)
if controller.perform_caching
if Rails.cache.exist?(cache_key)
html = Rails.cache.read(cache_key)
context.text_node(html)
else
Arbre::Element.new(context).build(&block)
Rails.cache.write(cache_key, context.current_arbre_element.content)
end
end
end |
Beta Was this translation helpful? Give feedback.
-
A new approach to caching Arbre content that is less prone to miss elements. The improvement is tracking which elements were added and building a string to cache from their content. Available as a gist: https://gist.github.com/zorab47/eda38bc72a5d1153b73b # Caches Arbre elements in the `Rails.cache`.
#
# Yielding the first time adds to the output buffer regardless of the
# returned value. A cache miss must be handled separately from a hit
# to avoid double rendering.
#
# Returns yielded Arbre on cache miss OR an HTML string wrapped in
# an text node on cache hit.
def cache_arbre(context, *args, &block)
if controller.perform_caching
if Rails.cache.exist?(*args)
context.text_node(Rails.cache.read(*args))
else
Rails.cache.write(*args, arbre_appended_children_content(context, &block))
end
else
yield
end
end
# Returns HTML content for Arbre elements appended to a context.
#
# Due to the complexities of Arbre content buffering it is difficult to get
# the content of an arbitrary set of Arbre elements without the use of a
# wrapping element like a `div`.
#
# Example
#
# Arbre::Context.new do
# h1 "Capturing Children Content"
#
# content = arbre_appended_children_content(self) do
# para "Paragraph 1"
# para "Paragraph 2"
# end
# end
#
# content # => "<p>Paragraph 1</p>\n<p>Paragraph 2</p>\n"
#
# Unlike this simple example which only returns the content of Paragraph 2
# because it is the only object returned from the block.
#
# Arbre::Context.new do
# h1 "Example of "
#
# content = begin
# para "Vanishing Paragraph 1"
# para "Paragraph 2"
# end.to_s
# end
#
# content # => "<p>Paragraph 2</p>\n"
#
def arbre_appended_children_content(context)
children = context.current_arbre_element.children
original_size = children.size
content = "".html_safe
result = yield
if (children.size > original_size)
content = "".html_safe
children[original_size .. -1].each do |child|
content << child.to_s
end
else
# No children added, return the output from yield. This could be when
# content was generated from a partial via `render`.
content = result.to_s
end
content
end |
Beta Was this translation helpful? Give feedback.
-
@varyonic do you think this workaround can be added to ActiveAdmin or Arbre? Otherwise I may pull it into a gem for convenience. |
Beta Was this translation helpful? Give feedback.
-
It looks plausible as an Arbre PR. I don't spend time on Arbre optimization as I have way more issues with ransack filters allowing expensive SQL. |
Beta Was this translation helpful? Give feedback.
-
Is there any way to perform Fragment caching with AA?? I couldn't make it work yet! |
Beta Was this translation helpful? Give feedback.
-
Maybe a stupid question.
I am wondering if it is possible to do fragment caching from AA DSL, something like :
Thanks,
Beta Was this translation helpful? Give feedback.
All reactions