Rails应用缓存问题:数据库数据已删除但Redis缓存仍存在
Hey there! The issue you're running into makes total sense—let's break it down and fix it quickly.
What's Going Wrong
Your current after_save :clear_cache callback only triggers when a Snippet is created or updated. When you run @snippet.destroy, Rails doesn't fire the after_save hook—so your Redis cache key "snippets" never gets deleted, leaving stale data behind.
The Fix: Cover Delete Operations in Your Callbacks
You have two solid options to make sure the cache gets cleared after deletions:
Option 1: Use after_commit (Recommended)
after_commit triggers after a database transaction is successfully committed, which covers create, update, AND destroy operations. This is more reliable than separate hooks because it avoids edge cases where a transaction might roll back but you've already cleared the cache.
Update your Snippet model like this:
class Snippet < ApplicationRecord # Trigger clear_cache after create, update, or destroy commits after_commit :clear_cache, on: [:create, :update, :destroy] def clear_cache $redis.del("snippets") end end
Option 2: Add an after_destroy Hook
If you prefer to keep separate hooks, explicitly add after_destroy :clear_cache to cover deletion events:
class Snippet < ApplicationRecord after_save :clear_cache after_destroy :clear_cache def clear_cache $redis.del("snippets") end end
Why This Works
Now when you delete a Snippet, the clear_cache method will run, deleting the "snippets" key from Redis. The next time someone hits the index action, your fetch_snippets helper will detect the missing cache key, pull the latest data from the database, and repopulate the cache with the updated list.
Just a quick check: make sure your fetch_snippets helper logic correctly re-populates the cache when it's missing. It should look something like this (adjust if your implementation differs):
# In SnippetsHelper def fetch_snippets cached_snippets = $redis.get("snippets") if cached_snippets JSON.parse(cached_snippets) else snippets = Snippet.all.to_a $redis.set("snippets", snippets.to_json) snippets end end
That should resolve the inconsistency—your cache will now stay in sync with the database after deletes!
内容的提问来源于stack exchange,提问作者user3576036

