-
Notifications
You must be signed in to change notification settings - Fork 21
Open
Labels
Milestone
Description
Since Curly has much more control of rendering when it takes place in a collection block, it should be possible to add smarter caching.
Given the template:
{{*comments}}
{{body}}
{{/comments}}... and presenter
class CommentPresenter < Curly::Presenter
presents :comment
def body
@comment.body
end
def cache_key
@comment
end
end... we should be able to generate Ruby that looks like this:
class Curly::RenderingContext
attr_reader :presenter, :value
def initialize(presenter, value)
@presenter, @value = presenter, value
end
def cache_key
@presenter.cache_key
end
end
contexts = presenter.comments.map {|value|
presenter = find_presenter_for(value) # pseudo code
Curly::RenderingContext.new(presenter, value)
}
# `fetch_multi` does a multi-get to the cache backend, so the cached fragments
# will be fetched in parallel. It gets the cache key for each item by calling `cache_key`
# on the object. Any object that was not found in the cache will be yielded, and the
# block's return value will be saved in the cache.
Rails.cache.fetch_multi(*contexts) do |context|
presenter = context.presenter
# code goes here.
endThat way, if the template is rendered with Comment records A and B, the nested template will be rendered for each and the results stored in the cache. The next time, there's a new Comment record C, so we'll have to render A, B, and C, but A and B are already stored in the cache. We'll do a single GET to the backend, get the pre-rendered HTML for both A and B and a miss for C, so we'll render the nested template with C.