ActiveRecord - CachedAt
¶ ↑
This gem causes ActiveRecord to update a cached_at column if present, like the updated_at column.
When calculating a cache_key for a model it will also consider the cached_at column to determine the key of a model.
Any ActiveRecord::Migration that calls timestamps will include a cached_at column.
Call to {ActiveRecord::Persistence::touch} will also touch the cached_at column.
Installation¶ ↑
Add the following line to your Gemfile:
gem 'activerecord-cached_at', require: 'cached_at'
If you just need the ActiveRecord::Base#cache_key and associated helpers and aren't updating the models you can just require the helpers:
gem 'activerecord-cached_at', require: 'cached_at/helpers'
Configuration¶ ↑
By default updates to the cached_at, updated_at, and created_at columns will not trigger and update to the cached_at column. You can add aditional fields to ignore:
class User cached_at ignore: :my_column end class Photo cached_at ignore: :column_a, :column_b end
Relationship Cache Keys¶ ↑
CachedAt also allows you to keep cache keys for relationships. This allows you to use the record to determine if a cache is valid for a relationship instead of doing another database query.
For example:
class User < ActiveRecord::Base has_many :photos end class Photo belongs_to :user, cached_at: true end bob_ross = User.create(name: 'Bob Ross') # => INSERT INTO "users" # ("name", "cached_at", "updated_at_", "created_at") # VALUES # ("Bob Ross", "2020-07-19 20:22:03", "2020-07-19 20:22:03", "2020-07-19 20:22:03") photo = Photo.create(user: bob_ross, file: ...) # =>INSERT INTO "photos" ("user_id", "cached_at", "updated_at_", "created_at") VALUES (1, "Bob Ross", "2020-07-19 20:22:04", "2020-07-19 20:22:04", "2020-07-19 20:22:04") # => UPDATE "users" SET "photos_cached_at" = "2020-07-19 20:22:04" WHERE "users"."id" = 1 photo.update(file: ...) # =>UPDATE "photos" (..., "cached_at", "updated_at_") VALUES (..., "2020-07-19 20:22:05", "2020-07-19 20:22:05", "2020-07-19 20:22:05") # => UPDATE "users" SET "photos_cached_at" = "2020-07-19 20:22:05" WHERE "users"."id" = 1 photo.update(user: not_bob_ross) # =>UPDATE "photos" ("user_id", "cached_at", "updated_at_") VALUES (2, "2020-07-19 20:22:06", "2020-07-19 20:22:06", "2020-07-19 20:22:06") # => UPDATE "users" SET "photos_cached_at" = "2020-07-19 20:22:06" WHERE "users"."id" IN (1, 2) photo.destroy # => UPDATE "users" SET "photos_cached_at" = "2020-07-19 20:22:07" WHERE "users"."id" = 2 # => DELETE FROM "users" WHERE WHERE "users"."id" = 2
Usage¶ ↑
cached_at will automatically be used for determining the cache key in Rails.
However if you need to calculate the cache key based on relationship cache keys you will need to manually compute the cache key. Examples are below:
The cache key here is the maxium of the following keys: cached_at, listings_cached_at, and photos_cached_at
<%= render partial: 'row', collection: @properties, as: :property, cached: Proc.new { |item|
[item.cache_key_with_version(:listings, :photos), current_account.id ]
} %>
<% cache @property.cache_key_with_version(:listings, :photos) do %>
<b>All the info on this property</b>
<%= @property.name %>
<% @property.listings.each do |listing| %>
<%= listing.info %>
<% end %>
<% @property.photos.each do |photo| %>
<%= image_tag(photo.url) %>
<% end %>
<% end %>
TODO:¶ ↑
-
Document going more than one level with cached_at keys
-
Add a
cache_keymethod to the Model class that getsMAX(cached_at) -
change option to cache: true
-
add cache_association helper