Rails页面缓存和flash消息

时间:2010-02-26 17:44:26

标签: ruby-on-rails caching page-caching

我很确定我可以对我网站的绝大多数网页进行页面缓存,但阻止我这样做的一件事就是我的flash消息不会显示,或者它们会在错误的时间显示。

我正在考虑的一件事是将Flash消息写入cookie,阅读并通过javascript显示并在消息显示后清除cookie。 有没有人有这样的成功或有更好的方法吗?

感谢。

7 个答案:

答案 0 :(得分:7)

可缓存的闪存执行此操作:

在您的应用程序控制器中:

after_filter :write_flash_to_cookie


def write_flash_to_cookie
    cookie_flash = cookies['flash'] ? JSON.parse(cookies['flash']) : {}

    flash.each do |key, value|
        if cookie_flash[key.to_s].blank?
            cookie_flash[key.to_s] = value
        else
            cookie_flash[key.to_s] << "<br/>#{value}"
        end
     end

    cookies['flash'] = cookie_flash.to_json
    flash.clear
end

然后通过Javascript读取“flash”cookie并在HTML中插入消息

答案 1 :(得分:4)

我正在处理同样的问题,我发现cacheable-flash插件完全符合KJF在问题中所描述的内容。

我认为这比进行过多的ajax调用更简单,更好。

答案 2 :(得分:2)

一种解决方案是缓存页面,但包含一个javascript代码段,它会针对您想要动态的部分发出另一个小请求。因此用户将完全下载页面,然后当javascript执行时,它将下拉动态页面元素。

我写了一篇关于此的短篇博文。 http://chase.ratchetsoftware.com/2008/12/rails-caching-dynamic-fragments/

此外,RailsEnvy的Greg Pollack做了一个截屏视频,他专注于在缓存页面中提供动态数据。 http://railslab.newrelic.com/2009/02/05/episode-5-advanced-page-caching

希望这有帮助,

蔡斯格雷

答案 3 :(得分:0)

您不必缓存整个页面。尝试片段缓存API

答案 4 :(得分:0)

老问题......但我通过将flash消息包含在我的缓存密钥中来解决这个问题。

caches_action :show, cache_path: proc { |c|
  most_recent_update_time = MyClass.order('updated_at DESC').limit(1).first.try(:updated_at).to_i
  { tag: most_recent_update_time.to_s + c.flash.collect{|x| x}.join }
}

如果您的show动作中有flash消息,这显然会经常破坏缓存,但如果您没有做很多消息,那么效果很好。

答案 5 :(得分:0)

Unobtrusive Flash将Flash消息放入cookie中,并通过JavaScript显示它。它提供了vanilla和Bootstrap风格的JS显示逻辑。它适用于普通和ajax请求。也很容易挂钩到像AngularJS这样的框架。

答案 6 :(得分:-1)

我不使用Rails,但这是我在Python中使用UUID的方式:

# set flash messages like this
def flash(self, title, body):
  session['flash_messages'].append({
    'title': title,
    'body': body,
    'uuid': uuid().hex  # stores a UUID as a string
  })

...

self.flash('foo', 'bar')

然后在基本模板中我有:

<script type="text/javascript">
  {% for m in session.flash_messages %}
    if(!Cookies.get('{{m.uuid}}')) {
      Notify('{{m.title}}', '{{m.body}}');
      Cookie.set('{{m.uuid}}', 'true', 86400); // key, value, expiry seconds
    }
  {% endfor %}
</script>

我会为Python-challenged打破它:

  1. 添加Flash消息时,您将创建一个唯一ID并将其与该消息一起存储。
  2. 在显示消息之前,您需要检查是否已设置以消息的唯一ID命名的cookie。
  3. 如果尚未设置该cookie,请刷新消息并设置cookie。在一天内过期cookie,或者您认为明智的简短。
  4. 现在,如果从缓存中提取此页面,则可以。在第2步,cookie的测试将通过,因为它已经设置,并且不会显示消息。