Caching in Rails

2 Min. Read
Aug 21, 2019

What is Caching

Caching is a technique which implements a cache (a hardware or software component) to store data or information that is either frequently used or isn’t subject to change anytime soon. In addition to that, caching can aid in boosting performance, in our context, of a web application, as the pages and controls are dynamically generated, which in turn further enhances the end user experience. So, we ought to cache data and information as much as and whenever possible. It is extremely important to cache data related transactions or queries to the database as they have significant effect over the response time of our application. Subsequent requests for the data will be fulfilled by the cache, as long as the cache is not expired. If the cache is expired, fresh data is obtained and the cache is refilled.

Amongst other caching technique provided by rails, low level caching makes use of Rails.cache method. We are made available a method named Rails.cache.fetch that takes in 3 arguments: a cache key, an optional hash and a block. It first looks for key’s value in the cache, if it is available, returns it, otherwise, executes the block and saves it in the cache.

Let us have a look at an example that takes returns the count of male and female from a survey. The data is unlikely to change anytime soon, and since the number of surveyees is large, the process of generating the count is an expensive one.

1
2
3
4
5
6
7
8
9
10
 def get_count
    male=0
    female=0
    Submissions.all.each do |sub|
      sub.survey_data['family_member'].each do |member|
        member['member_gender'] == 'gender_male' ? male=male+1 : female=female+1
      end
    end
    {all: male+female, male: male, female: female}
 end

The above code is a private method in the controller that returns count of total population from the surveyees’ data and also count of male and female. Since that number doesn’t change unless the number of surveyed subjects’ responses (Submissions) have changed. So, it is better to wrap the function in a block with Rails.cache.fetch method.

1
2
3
4
5
6
7
8
9
10
11
12
 def get_count
  Rails.cache.fetch('#{Submission.all.count}-male-female', expires_in: 1.day) do
    male=0
    female=0
    Submission.all.each do |sub|
      sub.survey_data['family_member'].each do |member|
        member['member_gender'] == 'gender_male' ? male=male+1 : female=female+1
      end
    end
    {all: male+female, male: male, female: female}
  end
 end

Likewise, Rails provides other caching features like Page Caching, Fragment Caching, etc. You can read all about them here