You have two options:
Option 1: do not cache voices
This is the simplest solution that I personally recommend. You just donโt cache the dynamic user-dependent part, so you have something like this:
# posts/_post.html.slim - cache post do h1 = post.title = post.text = render 'votes/form', post: post
Option 2: use javascript
This solution is more complex, but it actually does basecamp (however, mostly with simpler examples). You have both parts made on the page, but delete one of them using javascript. Here is an example using jQuery and 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 %>
Would I, however, change the voted? method correctly voted? to accept the identifier, so you do not need to make a new request. You can learn more about this approach at these railscasts: http://railscasts.com/episodes/169-dynamic-page-caching-revised?view=asciicast
source share