如何在Rails 4中缓存个性化片段?

时间:2013-06-17 18:01:35

标签: ruby-on-rails ruby caching

我的应用(Rails 4)允许用户对帖子进行投票。是否可以缓存帖子,但个性化投票缓存,以便显示一个针对current_user的个性化?例如,用户是否投票。

我宁愿不改变html结构来实现这一点。

# posts/_post.html.slim
- cache post do
  h1 = post.title
  = post.text
  = render 'votes/form', post: post

# votes/_form.html.slim
- if signed_in? && current_user.voted?(post)
  = form_for current_user.votes.find_by(post: post), method: :delete do |f|
    = f.submit
- else
  = form_for Vote.new do |f|
    = f.submit

2 个答案:

答案 0 :(得分:6)

这里有两个选项:

选项1:不缓存投票

这是最简单的解决方案,也是我个人推荐的解决方案。你只是不缓存动态用户相关部分,所以你有这样的东西:

# posts/_post.html.slim
- cache post do
  h1 = post.title
  = post.text
= render 'votes/form', post: post # not cached

选项2:使用javascript

这个解决方案更复杂,但实际上是basecamp如何做到这一点(但主要是用更简单的例子)。您在页面上呈现了两个部分,但使用javascript删除其中一个部分。以下是使用jQuery和CoffeeScript的示例:

# posts/_post.html.slim
- cache post do
  h1 = post.title
  = post.text
  = render 'votes/form', post: post

# votes/_form.html.slim
div#votes{"data-id" => post.id}
  .not_voted
    = form_for current_user.votes.find_by(post: post), method: :delete do |f|
      = f.submit
  .voted
    = form_for Vote.new do |f|
      = f.submit

# css
.not_voted {
  display:none;
}

# javascript (coffeescript)
jQuery ->
  if $('#votes').length
    $.getScript('/posts/current/' + $('#votes').data('id'))

# posts_controller.b
def current
  @post = Post.find(params[:id])
end

# users/current.js.erb
<% signed_in? && current_user.voted?(@post) %>
  $('.voted').hide();
  $('.not_voted').show();
<% end %>

但我会正确地更改voted?方法以接受ID,因此您无需进行新查询。您可以在此railscast中了解有关此方法的更多信息:http://railscasts.com/episodes/169-dynamic-page-caching-revised?view=asciicast

答案 1 :(得分:1)

尝试以下操作,这将为每个帖子的投票和未投票创建2个不同的片段。它将根据其状态进行阅读。

# posts/_post.html.slim
- cache [post, current_user.votes.find_by(post: post)]do
  h1 = post.title
  = post.text
  = render 'votes/form', post: post