Use fragment caching from helper function

We have a helper function that fetches data and does some
computations. This helper is used mostly everywhere. We have now come
to the phase of optimization and come to the conclusion that some
caching will help speed things up. I good place to get a lot of bang
for a small investment would be to make use of the fragment caching in
Rails and we would like to utilize it in this function in order to
avoid to have to add the cache call everywhere.

Having looked at the code for ActionView#cache and
ActionController#cache_erb_fragment it seems that a block from the erb
template is needed. The problem is that we don’t have a block from the
template available in the helper function (without changing in the
function call in all templates…). Is there another way to get at the
caching functionality without having to re-write it ourselves?

/Marcus

Marcus B. wrote:

We have a helper function that fetches data and does some
computations. This helper is used mostly everywhere. We have now come
to the phase of optimization and come to the conclusion that some
caching will help speed things up. I good place to get a lot of bang
for a small investment would be to make use of the fragment caching in
Rails and we would like to utilize it in this function in order to
avoid to have to add the cache call everywhere.

Having looked at the code for ActionView#cache and
ActionController#cache_erb_fragment it seems that a block from the erb
template is needed. The problem is that we don’t have a block from the
template available in the helper function (without changing in the
function call in all templates…). Is there another way to get at the
caching functionality without having to re-write it ourselves?

/Marcus

http://caboo.se/doc/classes/ActionController/Caching/Actions/ActionCacheFilter/Fragments.html#M003918

You can use read_fragment and write fragment. So your helper can do
something like:

def generate_foo(id)
fragment_name = “foo_helper/#{id}”
if output = read_fragment(fragment_name)
output
else
output = do_something(id)
write_fragment fragment_name, output
end

output

end

if read_fragment(name) does not read a fragment, it simply returns nil.
So you can decide wether or not the execute your expensive method based
on that.