18

Something like

Rails.cache.delete('site_search_form')

doesn't seem to work. Is this possible? Thanks.

Ben Crouse
  • 8,290
  • 5
  • 35
  • 50

5 Answers5

55

ActionController::Base.new.expire_fragment(key)

  • 2
    ruby-1.8.7-p334 :007 > ActionController::Base.new.expire_fragment(:controller => 'main', :action => 'index') NoMethodError: undefined method `host_with_port' for nil:NilClass – pixelearth Sep 05 '11 at 01:00
  • 1
    As of Rails 3, fragment caches have a hash at the end, which is based on the contents of the view in which they are generated. This is so the cache is automatically busted if the view changes, but it makes it difficult to expire by key. You can tell Rails not to add the hash with `skip_digest: true` in the cache call. More info: https://www.reinteractive.net/posts/197-if-you-explicitly-expire-cached-fragments-opt-out-of-cache-digests – stephen.hanson Dec 08 '16 at 19:35
6

Cache fragment entries are created with a slightly different key than what you access with Rails.cache.

Use expire_fragment instead (you can send it to a controller): http://api.rubyonrails.org/classes/ActionController/Caching/Fragments.html#M000438

Dave Powers
  • 2,051
  • 2
  • 30
  • 34
Terry
  • 1,088
  • 6
  • 10
  • This doesn't work for me. If this doesn't work for you too try `Rails.cache.delete_matched 'views/site_search_form*'` – yivo Aug 15 '16 at 18:40
  • As of Rails 3, fragment caches have a hash at the end, which is based on the contents of the view in which they are generated. This is so the cache is automatically busted if the view changes, but it makes it difficult to expire by key. You can tell Rails not to add the hash with `skip_digest: true` in the cache call. More info: https://www.reinteractive.net/posts/197-if-you-explicitly-expire-cached-fragments-opt-out-of-cache-digests – stephen.hanson Dec 08 '16 at 19:34
2
Rails.cache.delete "views/site_search_form"
d0minikk
  • 49
  • 3
0

In Rails 5 I took the following steps to bust the cache without resorting to skip_digest: true. Our problem was that changing the value of I18n strings does not reflect in the computed cache digest so the cache would not get busted automatically.

Here is the view where the cache block is defined:

/ views/layouts/_footer.html.slim
- cache :footer do
  span= t('shared.footer')

Then in rails console I run:

fragment = ActionController::Base.new.view_context.cache_fragment_name(:footer, virtual_path: 'layouts/_footer.html.slim')
ActionController::Base.new.expire_fragment(fragment)

cache_fragment_name will figure out the digest based on the virtual_path keyword argument.

Hamed
  • 1,382
  • 11
  • 20
0

Another option, if you are using Redis as your cache store, is to search and delete from redis directly using the keys method.

# get direct Redis client from Rails cache store
redis = Rails.cache.redis

# search for your key
keys = redis.keys.grep(/site_search_form/)

# delete the keys
keys.each do |key|
  redis.del(key)
end
Peter P.
  • 3,221
  • 2
  • 25
  • 31