Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent storing nil value in rails cache?

I am using redis-store for caching in my application,I don't want to fetch the key and value if the value returns nil.

Rails.cache.fetch{"user_by_comment_id:#{params['comment_id']}"} do
 User.find_by_comment_id(params['comment_id'])
end

if it return the nil for the key "user_by_comment_id:#{params['comment_id']}",I don't want to store the key in my cache.Help me to solve this.

like image 940
Achaius Avatar asked Jul 05 '13 09:07

Achaius


People also ask

What does Rails cache clear do?

clear will clear your app cache. In that case rake tmp:cache:clear will just try to remove files from "#{Rails. root}/tmp/cache" but probably won't actually do anything since nothing is probably being cached on the filesystem.

What is fragment caching in Rails?

Fragment Caching allows a fragment of view logic to be wrapped in a cache block and served out of the cache store when the next request comes in. For example, if you wanted to cache each product on a page, you could use this code: <% @products.

Where is Rails cache stored?

Rails (as of 2.1) provides different stores for the cached data created by action and fragment caches. Page caches are always stored on disk. Rails 2.1 and above provide ActiveSupport::Cache::Store which can be used to cache strings.

How do I clear Rails console cache?

clear in the Rails console to clear the cache. Unfortunately there is no way (yet) to do it from the command line. We can add a rake task that will do this for us. Then we can execute ./bin/rake cache:clear and clear the Rails cache from the command line.


2 Answers

Update:

From rails 6.0.0, you can supply the skip_nil: true option while calling Rails.cache.fetch

Here

Thanks Rick Suggs for pointing this out.

like image 71
Van_Paitin Avatar answered Oct 13 '22 01:10

Van_Paitin


You can add methods in the Rails.cache class to handle your case (put that code in initializer somewhere):

   module ActiveSupport
   module Cache
    class Store
      def fetch_no_nil(name, options = nil)
        if block_given?
          options = merged_options(options)
          key = namespaced_key(name, options)

          cached_entry = find_cached_entry(key, name, options) unless options[:force]
          entry = handle_expired_entry(cached_entry, key, options)

          if entry
            get_entry_value(entry, name, options)
          else
            save_block_result_to_cache_if_not_nil(name, options) { |_name| yield _name }
          end
        else
          read(name, options)
        end
      end
      private
      def save_block_result_to_cache_if_not_nil(name, options)
        result = instrument(:generate, name, options) do |payload|
          yield(name)
        end
        write(name, result, options) unless result.nil?
        result
      end
    end
  end
  end

And then use :

Rails.cache.fetch_no_nil{"user_by_comment_id:#{params['comment_id']}"} do
 User.find_by_comment_id(params['comment_id'])
end
like image 43
Sucrenoir Avatar answered Oct 12 '22 23:10

Sucrenoir