Topic: Rails 2.3.8 Action Caching without layout (ajax and non-ajax requests)

Hi there,

I'm using Action Caching with Rails 2.3.8 on Heroku with Memcached (via Dalli Gem).

Without the layout parameter Action Caching works fine. However, as soon as I add layout => false I get problems: Normal non-ajax requests are cached fine, without the layout, as expected. But ajax requests are not properly cached: I get cache misses all the time. Then, when I log in to my app neither normal, nor ajax requests are cached at all.

I also tried to set :layout => Proc.new { |c| c.request.xhr? }
When I do that ajax and normal requests are properly cached (no matter if logged out or logged in)
but normal requests also cache the layout. Seems odd to me as normal requests should have :layout => false.
I'm trying to debug this for hours now, but I haven't got a clue what's going on so far. What especially confuses me
is that the logged in state of my app apparently has an influence on the caching behaviour.

Here is my full caching call (for the case of layout => false):

caches_action :index, :layout => false,
                      :cache_path => Proc.new { |c| c.params.clone.delete_if { |k,v| ['authenticity_token'].include?(k) }.merge(:xhr => c.request.xhr? ? 't' : 'f') }

I'd greatly appreciate any help on this!

Nico

Re: Rails 2.3.8 Action Caching without layout (ajax and non-ajax requests)

Okay, I debugged a bit more and found out what the problem is
(at least when locally in development environment). Inside the action cache content_for_layout
is called to get the content to be cached if layout is set to false. This causes
my ajax requests to be not cached because content_for_layout returns nil as
I don't render the layout with ajax calls, only a partial. So I do need to set
layout to true for ajax calls. However I can't do that the way I tried to, as
the layout param doesn't accept a Proc. So I overwrote part of the ActionCacheFilter class
to test the layout for a call method and call it if present. That works great locally!
However, in production on Heroku with Memcached it still won't work properly.
Ajax calls are not cached.

Re: Rails 2.3.8 Action Caching without layout (ajax and non-ajax requests)

Okay, works fine now! I slightly changed the way I overwrote the ActionCacheFilter.

Re: Rails 2.3.8 Action Caching without layout (ajax and non-ajax requests)

ncri wrote:

Okay, works fine now! I slightly changed the way I overwrote the ActionCacheFilter.

I have same problem please help me and tell me how i can change the ActionCacheFilter.
tanx

Re: Rails 2.3.8 Action Caching without layout (ajax and non-ajax requests)

I have same problem with ajax call request in rails 2.3.8.
when i set render :layout=>false, my ajax action not cache !! but when i remove it ,it work ok.
this problem occur for some ajax link but other ajax link work ok!!!
please help me & tell me how i can change ActionCacheFilter and which section of it must be changed, to solve this problem?
tanks.

Re: Rails 2.3.8 Action Caching without layout (ajax and non-ajax requests)

Hi,

what I did was this in an initializer:

module ActionController 
  module Caching
    module Actions

      protected

      class ActionCacheFilter 

        def before(controller)
          cache_path = ActionCachePath.new(controller, path_options_for(controller, @options.slice(:cache_path)))
          if cache = controller.read_fragment(cache_path.path, @options[:store_options])
            controller.rendered_action_cache = true
            set_content_type!(controller, cache_path.extension)
            options = { :text => cache }
            options.merge!(:layout => true) if cache_layout?(controller)
            controller.__send__(:render, options)
            false
          else
            controller.action_cache_path = cache_path
          end
        end

        def after(controller)
          return if controller.rendered_action_cache || !caching_allowed(controller)
          action_content = cache_layout?(controller) ? content_for_layout(controller) : controller.response.body
          controller.write_fragment(controller.action_cache_path.path, action_content, @options[:store_options])
        end

        private

        def cache_layout? controller
          layout = @options[:layout].respond_to?(:call) ? @options[:layout].call(controller) : @options[:layout]
          layout == false
        end

      end
    end
  end
end

Maybe there is a better way of doing this, but it works!

Now you can call caches_action with :layout => Proc.new { |c| c.request.xhr? } to make your ajax requests work fine when
non ajax requests are cached without layout.

Re: Rails 2.3.8 Action Caching without layout (ajax and non-ajax requests)

thanx i will check it.

Re: Rails 2.3.8 Action Caching without layout (ajax and non-ajax requests)

sorry,what is this file 's name?, and where i have create it(initializers directory?)??

Re: Rails 2.3.8 Action Caching without layout (ajax and non-ajax requests)

Yes, put it in initializers and call it whateveryoulike.rb ;-)

Re: Rails 2.3.8 Action Caching without layout (ajax and non-ajax requests)

I do this...  i call  caches_action in my controller:
but i see "undefined method `caches_action' for #<LoginController:0x2b8c000a9bc0>"

  def new_user
    caches_action  :new_user , :layout => Proc.new { |c| c.request.xhr? }       
  end

Re: Rails 2.3.8 Action Caching without layout (ajax and non-ajax requests)

You can't call caches action inside a method. Call it in the Controller Class directly instead, just like a before_filter for example...

Re: Rails 2.3.8 Action Caching without layout (ajax and non-ajax requests)

it works fine....
thank u ... very very thanx wink

Re: Rails 2.3.8 Action Caching without layout (ajax and non-ajax requests)

sorry,my friend... i have another problem with submit a form  in Rails 2.3.8.
all things in my old app(2.0.2) works fine but in rails 2.3.8 i have this problem:
when i submit a nonAjax form in my app(login) i see "ActionController::InvalidAuthenticityToken
"
error in my browser !!!  i user <%= form_for or <%= form_tag to create the form.i want to disable forgery_protection in my app.
thus in 'config/devepoment.rb' set config.action_controller.allow_forgery_protection = false but my app dont work and no page browsed.can u help me??

Re: Rails 2.3.8 Action Caching without layout (ajax and non-ajax requests)

hello ncri
i have used your given details these are good thanks for sharing all these it is good to read this but please can yo tell taht i have  a problem here
caches action is not available
this is the message i have got all so please.....
twilio api

Last edited by john_rambo (2012-02-11 07:01:29)