tags:

views:

333

answers:

4

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:

  1. Start the development server. I'm using Thin.
  2. Visit one of the actions in the app. So far I have '/', '/about', and '/signup'. The template for the action will be rendered correctly.
  3. 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 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!

+1  A: 

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.

alexebird
A: 

That bug was reported in #ramaze channel a week ago.. to deaf ears it seems since it hasn't been fixed yet.

Boiled Waffel
+2  A: 

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.

hrnt
Thanks for the reply. Reverting to 45db6fe... broke my app. I'm using the flash helper and it now throws an exception saying that it can't find the flash method. If I know what I think I know about bindings, it seems like this would be caused by the Haml rendering proc being bound to Object.new, which of course doesn't have the flash helper included.Using the haml.rb from 2dd1012b4a396fcf18b983cfa6a36cc30fe1c903 works for me.
alexebird
I have since noticed that using content (local var) instead of @content doesn't completely solve the caching problem. Without having looked into it too much, it seems like although the template is rendered correctly into the layout, the template itself has not been updated.
alexebird
Yeah, my original post was a bit confusing: The working haml.rb was as it was before commit 45db6. So to wrap things up, working haml.rb is in 2dd1012 :)
hrnt
I assume that using `content` instead of `@content` is not the proper fix, considering that even the Ramaze book uses `@content` in its examples.
hrnt
+2  A: 

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

manveru