Changing a serializer-level cache key with the key option does not change the cache key.
With a basic controller
class ZonesController < ApplicationController
def index
render json: Zone.all
end
end
and basic serializer
class ZoneSerializer < ActiveModel::Serializer
cache key: 'area', expires_in: 3.hours
attributes :type, :key
def type
'Feature'
end
def cache_key
@cache_key # for debug
end
end
I would expect the cache key to resemble something like:
area/24-20160217165512052884/attributes/63c314f796ba5ea3898d4a639a9448f4
When instead the key is:
zone/24-20160217165512052884/attributes/63c314f796ba5ea3898d4a639a9448f4
I've verified that the expected key is not present in the cache (memcache in my case). The incorrect key that is being set instead is present in the cache and does contain the cached value, so the cache itself is working.
ActiveModelSerializers Version (commit ref if not on tag): 0.10.4
Output of ruby -e "puts RUBY_DESCRIPTION": ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin16]
OS Type & Version: 10.12.2
Integrated application and version (e.g., Rails, Grape, etc): Rails 5.0.1, api mode
(e.g., provide any applicable backtraces from your application)
Occurs with both memcache/dalli and Rail's memory_store.
development.rb cache section:
# Enable/disable caching. By default caching is disabled.
if Rails.root.join('tmp/caching-dev.txt').exist?
config.action_controller.perform_caching = true
config.cache_store = :mem_cache_store, "localhost"
config.public_file_server.headers = {
'Cache-Control' => 'public, max-age=172800'
}
else
config.action_controller.perform_caching = false
config.cache_store = :null_store
end
cache key: 'some key'
the key is not working.
I also met this problem, it cause me some problems,when i generate different format json data for the same model in method Index and Show, it will confuse the two formats, as the cache key set by me not working, the cache data of two json format was treated as one, store in redis. I can't get two json formats for one object.
I checked the sourse code of gem, the key set in the model *Serializer was not used first.
This is the sourse code generating the key store in redis or other db.
the key like this: "interviews/20-20170324091427000000/attributes"
def object_cache_key
if object.respond_to?(:cache_key)
object.cache_key
elsif (serializer_cache_key = (serializer_class._cache_key || serializer_class._cache_options[:key]))
object_time_safe = object.updated_at
object_time_safe = object_time_safe.strftime('%Y%m%d%H%M%S%9N') if object_time_safe.respond_to?(:strftime)
"#{serializer_cache_key}/#{object.id}-#{object_time_safe}"
else
fail UndefinedCacheKey, "#{object.class} must define #cache_key, or the 'key:' option must be passed into '#{serializer_class}.cache'"
end
end
It call the method cache_key(maybe this: http://apidock.com/rails/ActiveRecord/Base/cache_key) first.
I thought I ran into this problem today too (hadn't seen the issue) but after a brief source dive it looks like this is just a bit of documentation confusion. cache_key comes from the model, so if you want to override it you need to override it there. If for some reason (I happened to have one but it's definitely a rare need) you want to override from the serializer itself, the method to override is object_cache_key. So assuming we have a model, controller, and serializer for Koala it looks like this:
class Koala
def cache_key
"#{super}/eucalyptus"
end
end
class KoalaController
def show
render Koala.find(params[:id])
end
end
class KoalaSerializer
attributes :id, :food, :claws
def object_cache_key
"#{object.cache_key}/from_serializer"
end
end
Most helpful comment
I thought I ran into this problem today too (hadn't seen the issue) but after a brief source dive it looks like this is just a bit of documentation confusion.
cache_keycomes from the model, so if you want to override it you need to override it there. If for some reason (I happened to have one but it's definitely a rare need) you want to override from the serializer itself, the method to override isobject_cache_key. So assuming we have a model, controller, and serializer forKoalait looks like this: