Rails页面缓存和Flash消息

10

我相信可以对我的大部分网站进行页面缓存,但有一件事情阻挡了我,那就是我的闪现消息会不显示或者在错误的时候显示。

我正在考虑的一个解决方法是将闪现消息写入 cookie,在通过 JavaScript 读取和显示它,并在消息被显示后清除 cookie。

有没有人尝试过这样做并获得成功,或者有更好的方法?

谢谢。

7个回答

8
可缓存的 Flash 实现如下:
在您的应用程序控制器中:
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中。

4
我正在处理相同的问题,我发现 cacheable-flash 插件正好可以实现 KJF 在问题中描述的功能。
我认为这比进行过多的ajax调用更简单、更优雅。

我认为这是Rails的最佳方法。这个问题的大多数其他答案都建议自己构建,但cacheable-flash gem已经解决了这个问题,并且解决得很好。感谢Anton和Pivotal Labs。 - GregT

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 希望这可以帮到你。
Chase Gray

我喜欢这个想法。看起来它可能是解决问题的方法。 - KJF
1
我认为值得注意的是,这种做法无法充分发挥页面缓存的优势,因为Rails进程仍然会受到每次请求的打击,而不是完全不受影响。然而,我想不出更好的解决方案了。 - John Topley
3
使用片段缓存比再次发起仅请求第一个请求中包含的数据的第二个HTTP请求更好。这种策略会使您提供的HTTP请求数量翻倍。 - Jesse Dhillon

0

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


也许他想要缓存整个页面?页面缓存可以提供最大的性能提升。 - John Topley
是的,正确。我目前正在进行片段缓存,以解决闪存问题。 - KJF

0

不显眼的Flash 把Flash消息放入cookie中,然后通过JavaScript显示它。它提供了原始和Bootstrap风格的JS显示逻辑。它能够在正常请求和ajax请求中工作。它也很容易与AngularJS等框架连接。


0

这是一个老问题...但我通过将闪存消息包含在我的缓存键中来解决了它。

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消息,这显然会经常破坏缓存,但如果您没有发送大量消息,则效果很好。

-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 编程有困难的人们解释一下:

  1. 当你添加一个闪现信息时,你会创建一个唯一的 ID 并将其与该信息存储。
  2. 在显示信息之前,你需要检查一个名为闪现信息唯一 ID 的 cookie 是否已被设置。
  3. 如果该 cookie 尚未设置,则闪现信息并设置 cookie。将 cookie 在一天后或你认为合适的时间内过期。

现在,如果这个页面从缓存中拉出来,它就没问题了。在第二步,对于 cookie 的测试将通过,因为它已经被设置了,而且信息也不会被显示。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接