ActiveRecordis the default object relational model of the Rails web framework. It obviously follows the active record architectural pattern. Now,
ActiveRecordmaintains it own query cache which is different from the query cache of the underlying database server. This query cache is a rather simplistic one.
The issue that brought the requirement of query cache bypassing into picture was as follows.
1. a call to first object of the model to check if any records existed (Model.first)
2. raw SQL query to truncate the table
3. a call again to first object of the model to check if any records existed (Model.first)
Now, #1 and #3 obviously generated same SQL query. So,
ActiveRecordserved #3 from its cache.
We found multiple approaches of bypassing the
Clear the entire
ActiveRecordcache. In Rails 2 this can be done using
In Rails 3, the same can be achieved using the following line.
This approach however would clear the entire
ActiveRecordcache which in production environment means increasing load on database server which is already the bottleneck. Plus, this approach is like using a jack hammer where a finger-tap would work.
This approach exploits the simplicity of the
ActiveRecordcache. It forms the query in such a manner that the query string is very likely to be different from previous queries.
r = call random number generator
where_clause = "r = r"
Appending the above where clause to #1 and #3, we obtained queries that are very likely to be different from previous ones at least within the life time of the cache. This approach is obviously not elegant.
In this approach, we went with raw SQL queries not only for #2 but also for #1 and #3.
ActiveRecorddoes not seem to cache raw SQL queries. So we could replace the call to the 'first' method of the model with something similar to the following.
sql = "select * from table_name limit 1"
Although we can get the job done by this approach, it is bad practice to execute raw SQL.
Finally, we found a way of doing it through Rails. We need to explicitly tell Rails not to serve our queries from its cache for #1 and #3. This can be done as follows.
As this method does the job using the Rails framework, the abstraction all provided by ActiveRecord remains unbroken.