Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Manually Generating Rails Cache Key

I'm trying to use isolated workers to build and manipulate my cache. I would like to keep these workers as lean as possible. (don't use rails)

I'm having difficulty forging rails generated cache keys

In my view I have this:

cache ["comments", @ama]

I'm trying to replicate the key that it produces with the following:

updated_at = Time.parse(row['updated_at'])
timestamp = updated_at.utc.strftime('%Y%m%d%H%M%S')
cache_key = "views/comments/amas/#{row['id']}-#{timestamp}"

Which will produce:

views/comments/amas/432-20121227010114

The cache from that key is blank.

Either I'm not formatting my key correctly, or the cache is missing. I'm 95% confident the cache i'm seeking is there.

(I'm able to push cache with a key such as 'test', and then get it back. So I know the caching is working)

Helpful References:

  • http://apidock.com/rails/ActiveRecord/Base/cache_key
  • http://apidock.com/rails/ActiveSupport/CoreExtensions/Time/Conversions

Helpful Information:

  • The cache server isn't local, and yes I'm pointing to it.
  • Even if the key didn't exist, When I load the page in production the key & cache would be built on the spot. Which I have tried.
  • using Rails 4.0.0
like image 571
Andrew Wei Avatar asked Jul 15 '13 00:07

Andrew Wei


People also ask

How can you implement caching in Rails?

You can create your own custom cache store by simply extending ActiveSupport::Cache::Store and implementing the appropriate methods. This way, you can swap in any number of caching technologies into your Rails application. To use a custom cache store, simply set the cache store to a new instance of your custom class.

Where does Rails store cache?

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.

Does Rails cache use Redis?

Rails 5.2 introduced built-in Redis cache store, which allows you to store cache entries in Redis.


2 Answers

The most efficient way to implement low-level caching is using the Rails.cache.fetch method. It will read a value from the cache if it available; otherwise it will execute a block passed to it and return the result:

You can manually set the cache key from rails console(by typing 'rails c' in command prompt)

>> Rails.cache.fetch('answer')
==> "nil"
>> Rails.cache.fetch('answer') {1 + 1}
==> 2
Rails.cache.fetch('answer')
==> 2

Consider the following example. An application has a Product model with a class method returning all out of stock items, and an instance method that looks up the product’s price on a competing website. The data returned by these methods would be perfect for low-level caching:

# product.rb

def Product.out_of_stock
  Rails.cache.fetch("out_of_stock_products", :expires_in => 5.minutes) do
    Product.all.joins(:inventory).conditions.where("inventory.quantity = 0")
  end
end

def competing_price
  Rails.cache.fetch("/product/#{id}-#{updated_at}/comp_price", :expires_in => 12.hours) do
    Competitor::API.find_price(id)
  end
end

I think it will be helpful for you.

Thanks.

like image 165
Amit Avatar answered Oct 19 '22 05:10

Amit


template cache keys look like this:

views/projects/123-20120806214154/7a1156131a6928cb0026877f8b749ac9
       ^class   ^id ^updated_at    ^template tree digest

Reference: http://api.rubyonrails.org/classes/ActionView/Helpers/CacheHelper.html#method-i-cache

like image 33
Andrew Wei Avatar answered Oct 19 '22 05:10

Andrew Wei