nesquena / rabl

General ruby templating with json, bson, xml, plist and msgpack support
http://blog.codepath.com/2011/06/27/building-a-platform-api-on-rails/
MIT License
3.65k stars 335 forks source link

Rendering a template out of Controller scope does not append digest hash of template to cache_key #546

Open blotto opened 10 years ago

blotto commented 10 years ago

I'm using Rails 4.0.2, and want to background rendering of objects for cache warming, prior to a Controller action ever being hit for certain APIs.

When rendering a template from a Controller action, I get the expected cache actions showing the below cache keys. In this case, the template's cache digest is d30440d18014c72014a05319af0626f7

Cache read: rabl/activities/26600-20140423170223588554000//hash/d30440d18014c72014a05319af0626f7 
Cache generate: rabl/activities/26600-20140423170223588554000//hash/d30440d18014c72014a05319af0626f7 
Cache write: rabl/activities/26600-20140423170223588554000//hash/d30440d18014c72014a05319af0626f7

When calling Rabl::Render out of the Controller's scope I get a different cache_key, basically without the temaplte digest appended to the end.

Rabl::Renderer.new('api/v2/activities/show_no_root', @activity, {:view_path => 'app/views', :format => :json, :scope => self}).render
Cache read: rabl/activities/26600-20140423170223588554000//hash
Cache generate: rabl/activities/26600-20140423170223588554000//hash
Cache write: rabl/activities/26600-20140423170223588554000//hash

I realize this is a scoping issue, but its not clear what the scope should be in the cache warming use case. Passing self be it the Model, Observer, or some Helper class doesn't provide the scope necessary for the template digest to be appended to the cache_key. When passing the Controller through this does work as expected, but this is not available during the attempt to warm the cache through a background process. Maybe this approach is totally incorrect?

blotto commented 10 years ago

I could not find a solution with Rabl::Render to warm a cache, but am able to use this method as a background process effectively. I think this is a bit too heavy, and still think there is a more elegant solution out there with Rabl::Render.

#example
cache_warmer( :api_v2_expensiveapi_url, args_array , params_hash)
#method
def cache_warmer( url_helper, args, params={},method='get')
     if method == 'get'
       session = ActionDispatch::Integration::Session.new(Rails.application)
       session.get(session.send(url_helper, *args), params)
     end
end

kept issue open as I think this is worth a discussion on how or why not Rabl::Render can provide this

nguyenmighty commented 8 years ago

I'm running into the same issue here. Rails haml has the ability to skip_digest, and I think the same option should be available for RABL caching as well.