I have the following structure in my rails4 app for the posts. Users can comment on the post and replies can be written on the comments. I'd like to use russian-doll-caching with auto-expiring keys on the page, but I don't know how I should exactly do it in this case.
Can sby tell me how to use it in this case?
Models:
#post.rb
belongs_to :user
has_many :post_comments, dependent: :destroy
#post_comments.rb
belongs_to :user
belongs_to :post
has_many :post_comment_replies, dependent: :destroy
#post_comment_replies.rb
belongs_to :user
belongs_to :post_comments
posts/index.html.erb
<div class="post-index new-post-insert">
<%= render @posts %>
</div>
_post.html.erb
<%= post.body %>
<%= post.user.full_name %>
....
<%= render partial: 'posts/post_comments/post_comment', collection: post.post_comments.ordered.included, as: :post_comment, locals: {post: post} %>
_post_comment.html.erb
<%= post_comment.body %>
<%= post_comment.user.full_name %>
......
<%= render partial: 'posts/post_comment_replies/post_comment_reply', collection: post_comment.post_comment_replies.ordered.included, as: :post_comment_reply, locals: { post_comment: post_comment } %>
_post_comment_reply.html.erb
<%= post_comment_reply.user.full_name %>
<%= post_comment_reply.body %>
You need to do a few things
Add touch to your
belongs_to
relationsThe children and grandchildren of
Post
needs to touch their parents so that theupdated_at
column updates which in turn invalidates the cache keys.Add the
cache
command to your viewsposts/index.html.erb
In the main list of posts we want to cache on the latest
updated_at
for posts and the latestupdated_at
for the respective user._post.html.erb
_post_comment.html.erb
_post_comment_reply.html.erb
This could be improved by using
cached: true
in therender partial
function. However since we want to expire the cache if the user changes their username it becomes a bit tricky.You can do that if you override all the models
cache_key
functions.Why should I use
cached: true
inrender partial
?Instead of calling
cache
inside each partial (like we do above) we could doIf we only need to cache on the post_comment´s
updated_at
.The difference between the two are that when we cache inside the partial Rails issues a
get
command to the cachestore (e.g. memcache) one time per object. Therefore if you have 50 postcomments, there will be 50 separate requests to memcached to retrieve all.But if we instead use cached: true in the
render
call Rails will issue amulti_get
request to memcached and retrieve all 50 objects in one request. Thus improving page loadtime. In tests we have conducted in our production env. it decreased the page loadtime by ~50ms - ~200ms depending on the amount of data.