Ramaze's Haml engine returns same template every time
I've run into a problem with my very simple Ramaze project. My project is identical to the prototype project that is generated from 'ramaze create mywebsite', except that I'm using Haml templates (I set 'engine :Haml' in controller/init.rb).
Here are the steps to reproduce the problem:
- Start the development server. I'm using Thin.
- Visit one of the actions in the app. So far I have '/', '/about', and '/signup'. The template for the action will be rendered correctly.
- Visit a different action. This time the exact same thing which was rendered for the first action will be returned.
Only the first request after starting the 开发者_C百科dev server will be rendered correctly.
I only think it has something to do with Haml because after switching back to the default engine for Ramaze, everything works as it should. All of my gems are up to date.
Any ideas?
Thank you!
Fixed it by reverting some supposed improvements to the way Ramaze handles Haml views. It would cache the result of the layout even though the @content variable changed. I also added a spec so this can't happen in the future: spec/ramaze/view/haml.rb
Can you try reverting haml.rb to the state it was before commit 45db6fe0696dfac7deeebba42c62c6bcca8bab10 on your Ramaze? That fixed the bug on my app.
I assume the bug is caused by this:
New haml.rb causing the bug:
haml = View.compile(string) do |s|
::Haml::Engine.new(s,options).render_proc(action.instance,*action.variables.keys)
end
The return value of render_proc
is cached. The key used is, AFAIK, the checksum of the unprocessed layout Haml. The problem is that render_proc
binds here to action.instance where @content
is stored.
This means that every time we are rendering a page using the same layout (and thus the same cache key), we are using the same action.instance
we used when rendering the first page. The result is that we always get the same layout filled with the same instance variables.
I think the person who did that patch assumed that people used local variables (content
) in their layout instead of instance variables (@content
). Indeed, if content
is used instead of @content
in the layout, the bug seems to disappear.
Figured out a workaround! The problem is involved with the Innate::View caching system. By disabling view caching:
Innate::View.options.cache = false
the problem is fixed. Obviously this isn't ideal, but I'd rather not cache views and use Haml for the time being. I spent some time trying to figure out what was wrong in Innate::View but I didn't find anything.
That bug was reported in #ramaze channel a week ago.. to deaf ears it seems since it hasn't been fixed yet.
精彩评论