I have an action on a controller where I'm using action caching. However I'm using the layout: false flag on that caching call since my layout has user dependent information like login status. This works perfectly.
Then I was adding the pjax-rails gem, which basically adds this code to the controller:
layout ->(c) { pjax_request? ? false : 'application' }
That is on some requests the layout isn't rendered. Now I (kinda logically) want to combine these two approaches together.
However when pjax_request? == true I get this error:
There was no default layout for MyController
What am I doing wrong and how can I solve this problem?
PS: This is easiest reproducible in this case:
class MyController < ApplicationController
layout false
caches_action :index, :layout => false
def index
end
end
I almost think this might be a bug in Rails. Check out this block of code around line 143 of actionpack/lib/action_controller/caching/actions.rb:
body = controller.read_fragment(cache_path.path, @store_options)
unless body
controller.action_has_layout = false unless @cache_layout
yield
controller.action_has_layout = true
body = controller._save_fragment(cache_path.path, @store_options)
end
body = controller.render_to_string(:text => body, :layout => true) unless @cache_layout
controller.response_body = body
It looks like it's correctly rendering the body without a layout in the first unless block, but then it's forcing the template to render with a layout as part of the response body. And if you look at the stack trace, that's the line that leads to the exception.
I manually edited the file to :layout => @cache_layout (which always evaluates to :layout => false since it's guarded by an unless) and the view rendered as expected.
I'm not sure what you could do about this other than temporarily patch that file yourself and open a bug report. I might also be wrong about the behavior of that line, but it certainly looks like the culprit.
For anyone coming across this in the future, as of rails 3, setting a default layout to the controller:
layout "application"
http://apidock.com/rails/AbstractController/Layouts/ClassMethods/layout
Seem to overcome this issue, that is indeed a rails defect.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With