Rails 5 Wildcard for specifying template dependencies

Abhishek Jain

By Abhishek Jain

on August 17, 2016

This blog is part of our  Rails 5 series.

Cache Digests

After cache digests were introduced in Rails, all calls to #cache in views automatically append a digest of that template and all of its dependencies to the cache key.

So developers no longer need to manually discard cache for the specific templates they make changes to.

1
2# app/views/users/show.html.erb
3<% cache user do %>
4  <h1>All Posts</h1>
5  <%= render user.posts %>
6<% end %>
7
8# app/views/posts/_post.html.erb
9<% cache post do %>
10  <p> <%= post.content %></p>
11  <p> <%= post.created_at.to_s %>
12  <%= render 'posts/completed' %>
13<% end %>
14

This creates a caching key something like this views/users/605416233-20129410191209/d9fb66b12bx8edf46707c67ab41d93cb2 which depends upon the template and its dependencies.

So, now if we change posts/_completed.html.erb, it will change cache key and thus it allows cache to expire automatically.

Explicit dependencies

As we saw in our earlier example, Rails was able to determine template dependencies implicitly. But, sometimes it is not possible to determine dependencies at all.

Let's see an example below.

1
2# app/views/users/show.html.erb
3<% cache user do %>
4  <h1>All Posts</h1>
5  <%= render user.posts %>
6<% end %>
7
8# app/views/posts/_post.html.erb
9<% cache post do %>
10  <p> <%= post.content %></p>
11  <p> <%= post.created_at.to_s %>
12  <%= render_post_complete_or_not(post) %>
13<% end %>
14
15# app/helpers/posts_helper.rb
16
17module PostsHelper
18  def render_post_complete_or_not(post)
19    if post.completed?
20      render 'posts/complete'
21    else
22      render 'posts/incomplete'
23    end
24  end
25end
26

To explicitly add dependency on this template, we need to add a comment in special format as follows.

1  <%# Template Dependency: posts/complete %>
2  <%# Template Dependency: posts/incomplete %>

If we have multiple dependencies, we need to add special comments for all the dependencies one by one.

1
2# app/views/posts/_post.html.erb
3<% cache post do %>
4  <p> <%= post.content %></p>
5  <p> <%= post.created_at.to_s %>
6
7  <%# Template Dependency: posts/complete %>
8  <%# Template Dependency: posts/incomplete %>
9  <%= render_post_complete_or_not(post) %>
10<% end %>
11

Using Wildcard in Rails 5

In Rails 5, we can now use a wildcard for adding dependencies on multiple files in a directory. So, instead of adding files one by one we can add dependency using wildcard.

1
2# app/views/posts/_post.html.erb
3<% cache post do %>
4  <p> <%= post.content %></p>
5  <p> <%= post.created_at.to_s %>
6
7  <%# Template Dependency: posts/* %>
8  <%= render_post_complete_or_not(post) %>
9<% end %>
10

Stay up to date with our blogs. Sign up for our newsletter.

We write about Ruby on Rails, ReactJS, React Native, remote work,open source, engineering & design.