In today’s web application world, Normally the owner of an application or the admin will not think/care about the caching until or unless they have not faced any issue with application performance or in other words the slow user experience. To increase the performance of application developers will try to add an index to the relevant table or they will try to add fragment caching. However, probably this is not the right way to get rid of performance. So one of the primary aspect is that we should understand the process of how key-based caching in ruby on rails 5.2 works and how we can use it in our application.

Here I am going to explain about three type of caching:

(Now the aim is to combine all three methods optimally.)

1) HTTP Caching

This is the main caching weapon in ruby on rails, Every web pages that are used in our mobile devices should reach to HTTP caching. In case if you are using key-based cache expiration and HTTP Caching, then it will greatly help us to save huge amount of processing time for the server and bandwidth.

What Is HTTP Caching?

HTTP caching will try to reuse already loaded web pages, images or files. For example, if you visit a site like – ‘https://www.agiratech.com/’ multiple time in a day then it will not load all the content every time from the server on your next visit, few contents will be loaded from the browser cached.

Concepts Of HTTP Caching

In HTTP Caching, we have a very nice concept called last modified, Which means the “Web browser will always have the information about the content like when the particular web page was last loaded or downloaded. Secondly, the request will serve the content which are stored in the cache, but before that, it will check and compare the information to the corresponding file that either delivers a newer version or return an HTTP 304 Not Modified code as a response. Finally, If the information is fresh and modified then it will give us the updated data otherwise it will serve the cached data.

fresh_when will generate the Last-Modified entry in the HTTP header in the controller. so, let me show you how we can create in Controller,

In your controller method add this,

def show fresh_when last_modified: @company.updated_at end 1 2 3 def show fresh_when last_modified : @ company . updated_at end

Now you can see the Magic of touch . Yes! “touch” is the magic keyword we’re going to use here. Just add the below line in your model and see what it does,

belongs_to :company, touch: true 1 belongs_to : company , touch : true

The object of an employee will get saved if we use the touch: true in the model.

If we save the employee table with touch:true then it will automatically update the dependent table. Here i have named this table as “Company database” and you can name it with whatever you wish,

There will be a field like “ updated_at field” so automatically it will get updated by the current time and if it happens then we can confirm it that the record is touched, this approach will also confirm that it is delivering the correct content.

2) Page Caching

Page caching was removed from the core of Rails 4.0, but it is still available as a gem, and it is powerful also. To do page caching, you need a bit of knowledge to configure your web server (e.g., Nginx or Apache). Page caching is not for the faint-hearted.

Note: Remember the Page Caching has been removed from Rails 4 and it is still available as Gem.

With page caching, it’s all about placing a complete HTML page and in other words, the render result of a view into a subdirectory of the public directory will be directly delivered by the web server whenever the web page get visited by the second time.

Additionally, you can also save a compressed .gz version of the HTML page there. Here another advantage is that the production web server will automatically deliver the files which are saved under public itself and we can also be configure and customize it so that any .gz files which are present there will be delivered directly.

When programming your Rails application, please ensure that you also update this page or just delete it! Because based on that file only your entire caching mechanism will work so that it is advisable and it would be better if’re not keeping this file for long. Since we yet to cover so many topics so am not writing this concept now but by chance if you wanted to know then you could find the description of “ How to Delete the Page Caches Automatically.” here otherwise, you will end up with an outdated cache later.

How To Activate Page Caching In Development mode?

Activating Page Caching in Development Mode requires you to do some modification in config file.

config.action_controller.perform_caching = true 1 config . action_controller . perform_caching = true

Otherwise, you cannot try page caching in development mode. In production mode, page caching will be enabled by default.

3) Fragment caching

Using this caching, we can cache the individual parts of the web page/view. Also we can safely use it with a combination of HTTP and Page caching. However, the advantages of both are the same here because all the caching will reduce the server load and helps in generating the web pages fastly. Alongside it also helps to increase your application performance.

Enable The Fragment Caching

Defaultly Fragment caching is disabled in development mode, if you want to enable it then just run the below command

rails dev:cache 1 rails dev : cache

This command will change the below file,

file tmp/caching-dev.txt. $ rails dev:cache *****Development mode will get cached***** 1 2 file tmp / caching - dev . txt . $ rails dev : cache * * * * * Development mode will get cached* * * * *

To deactivate that caching and run the same command now the fragment caching will get deactivated.

$ rails dev:cache 1 $ rails dev : cache

Output:

You will get to see this message.

[code] Development mode is no longer being cached.[/code]

In production mode, fragment caching is enabled by default.

Delete the fragment cache – with method expire_fragment, using expire_fragment we can clear the specific fragment caches. Normally we should use this in the model.

You can use it easily in models follow the below code snippet –

def expire_cache ActionController::Base.new.expire_fragment(‘table_of_all_companies’) end 1 2 3 def expire_cache ActionController :: Base . new . expire_fragment ( ‘ table_of_all _ companies’ ) end

There you can see that i have Defined the method called ‘expire_cache’ and also you can call that method with any of this actions like after_create, after_update.

What’s more in caching?

Yes , we have one more concept in Caching ,

Auto-expiring Caches

Maintaining the fragment caching is really complex when compared to the naming convention used in the ‘Caching the Table of the Index View,’. Anyway, You can assure that Caching doesn’t need any excessive efforts if you have done a proper implementation and neat alignment in your code. Therefore, basically, cache is structured in such a way that it will remove the old data if no longer required with some logic. If you can find a way or a mechanism and if that concept can able to serve you the fragment cache with a unique name then you no longer need to worry about deleting the fragment caches.

Sample example of code of rails view:

<% cache(@companies) do %> <table> <thead> <tr> <th>Name</th> <th>Number of employees</th> <th colspan=”3"></th> </tr> </thead> <tbody> <% @companies.each do |company| %> <tr> <td><%= company.name %></td> <td><%= company.employees.count %></td> <td><%= link_to ‘Show’, company %></td> <td><%= link_to ‘Edit’, edit_company_path(company) %></td> <td><%= link_to ‘Destroy’, company, method: :delete, data: { confirm: ‘Are you sure?’ } %></td> </tr> <% end %> </tbody> </table> <% end %> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <% cache ( @companies ) do %> < table > < thead > < tr > < th > Name < / th > < th > Number of employees < / th > < th colspan = ” 3 " > < / th > < / tr > < / thead > < tbody > <% @companies . each do | company | %> < tr > < td > <%= company . name %> < / td > < td > <%= company . employees . count %> < / td > < td > <%= link _ to ‘ Show ’ , company %> < / td > < td > <%= link _ to ‘ Edit ’ , edit_company_path ( company ) %> < / td > < td > <%= link _ to ‘ Destroy ’ , company , method : : delete , data : { confirm : ‘ Are you sure ? ’ } %> < / td > < / tr > <% end %> < / tbody > < / table > <% end %>

You can generate a cache key for the Companies table, to see the name of the key in the log that generated by rails, you just need to add below line in the file config/environments/development.rb to get to know the name of that keys,

config.action_controller.enable_fragment_cache_logging = true 1 config . action_controller . enable_fragment_cache_logging = true

There is no perfect answer for the question that how much details we should use in fragment caching, Though you can try some sample application, try the log and see how long things take.

Russian Doll Caching:

In the above code, we have created fragment caching for the entire table of companies, if any data changes within the table then the whole table needs to be re-rendered. Depending on the size of data, it may take longer then expected. Now you got the problem here, So to overcome from this Russian Doll caching, we have one more way to resolve it. Yes to solve this, we don’t need to cache the whole table but we can cache each row of the table. So when any update happens in the row then just change and re-render that particular row. So, all the other rows will be fetched from the cached. This can save many resources.

Sample example of code with a small change:

<% cache(@companies) do %> <table> <thead> <tr> <th>Name</th> <th>Number of employees</th> <th colspan=”3"></th> </tr> </thead> <tbody> <% @companies.each do |company| %> <% cache(company) do %> <tr> <td><%= company.name %></td> <td><%= company.employees.count %></td> <td><%= link_to ‘Show’, company %></td> <td><%= link_to ‘Edit’, edit_company_path(company) %></td> <td><%= link_to ‘Destroy’, company, method: :delete, data: { confirm: ‘Are you sure?’ } %></td> </tr> <% end %> <% end %> </tbody> </table> <% end %> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <% cache ( @companies ) do %> < table > < thead > < tr > < th > Name < / th > < th > Number of employees < / th > < th colspan = ” 3 " > < / th > < / tr > < / thead > < tbody > <% @companies . each do | company | %> <% cache ( company ) do %> < tr > < td > <%= company . name %> < / td > < td > <%= company . employees . count %> < / td > < td > <%= link _ to ‘ Show ’ , company %> < / td > < td > <%= link _ to ‘ Edit ’ , edit_company_path ( company ) %> < / td > < td > <%= link _ to ‘ Destroy ’ , company , method : : delete , data : { confirm : ‘ Are you sure ? ’ } %> < / td > < / tr > <% end %> <% end %> < / tbody > < / table > <% end %>

Change the Code in the view results as an Expired Cache

Usually Rails will track the MD5 view file we use. So if you modify the view file with abive mentioned row changes then the MD5 will get updated then all the old caches will be expired.

That’s all for caching in ruby on rails 5.2, do fun with caching and try to write cache friendly code to maintain a good performance of your websites.

Wish to read more? Then never miss out anything from our largest blog portal where you can get continuous blog updates & latest posts about all latest technologies which would be perfect for your 15 minutes tea break! In case if you’re a newbie then don’t forget to subscribe us to get the latest updates from diverse technologies. What else guys hit the subscribe link and go crazy over learning. For more inquires reach us via info@agiratech.com