Rails.cache.fetch đọc cache theo key; nếu chưa có (cache miss) thì chạy block, lưu kết quả rồi trả về.
def exchange_rate
Rails.cache.fetch('usd_vnd_rate', expires_in: 10.minutes) do
RateApi.fetch_usd_vnd # only runs on a miss
end
endKey phải chứa mọi thứ ảnh hưởng tới kết quả — id, locale, phiên bản dữ liệu.
Cách thông dụng là dùng chính record làm key vì cache_key_with_version đã gắn updated_at, nên khi record đổi thì key đổi, không cần đi xoá cache:
Rails.cache.fetch([user, 'unread_count'], expires_in: 1.hour) { user.notifications.unread.count }Lưu ý thực tế:
- Block không chạy khi có cache, nên đừng đặt side effect trong đó.
- fetch lưu cả nil/false được hay không tuỳ store; muốn chắc thì tránh cache giá trị rỗng hoặc dùng skip_nil: true.
- Nhiều request cùng miss một key nặng sẽ cùng lúc chạy block (cache stampede). Với key đắt tiền, dùng race_condition_ttl để một request gia hạn key cũ trong lúc tính lại.
- Store dùng chung (:redis_cache_store, :mem_cache_store) mới có tác dụng khi chạy nhiều process; :memory_store chỉ nằm trong một process.