How to cache a custom snippet in Rails 4?

My application (Rails 4) allows users to vote on posts. Is it possible to cache a message, but personalize the voting cache so that it displays one personalized for current_user? For example, whether the user voted or not.

I would prefer not to modify the html structure to achieve this.

# 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 
+6
source share
2 answers

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 # not cached 

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

+6
source

Try the following: it will create 2 different fragments for voting and will not vote for each post. It will be read according to its status.

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

Source: https://habr.com/ru/post/947490/


All Articles