When querying using #find or #find_by results are stored to cache. This helps Rails load some queries from the cache instead of overloading the database server. Each query is responsible for generating a cache key and storing the result in the cache. This causes some irregularities to appear.

Before

One small oversight was #find and #find_by(id: ...) using different cache keys. Both queries return the same result but do not store the result to the exact cache location.

Let’s look into how ActiveRecord Core works:

We can see here that the cache key is just for primary_key (which in most scenarios is "id").

Let’s go through the #find_by method that accepts a hash of attributes.

The cache key here gets set to hash.keys which returns an array of the columns that find_by searches with.

Which is where the ambiguity arises. While #find returns the cache key "id", find_by returns the cache key ["id"].

After

Rails ActiveRecord::Core “#find” now reuses “#find_by” cache key. Both queries use the same cache location.

Query Cache Key
find(123) [“id”]
find_by(id: 123) [“id”]
find_by(id: 123, foo: true) [“id”, “foo”]

It was a simple fix added to the #find method, which now pushes primary_key to an array.

Minor tweaks to core libraries can lead to huge benefits across applications!