Rails缓存密钥生成为ActiveRecord :: Relation [英] Rails Cache Key generated as ActiveRecord::Relation

查看:100
本文介绍了Rails缓存密钥生成为ActiveRecord :: Relation的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试生成片段缓存(使用Dalli/Memcached存储),但是该密钥是使用#"作为密钥的一部分来生成的,因此Rails似乎无法识别出存在缓存值并访问数据库.

I am attempting to generate a fragment cache (using a Dalli/Memcached store) however the key is being generated with "#" as part of the key, so Rails doesn't seem to be recognizing that there is a cache value and is hitting the database.

我在视图中的缓存键如下:

My cache key in the view looks like this:

cache([@jobs, "index"]) do

控制器具有:

@jobs = @current_tenant.active_jobs

使用像这样的实际Active Record查询:

With the actual Active Record query like this:

def active_jobs
   self.jobs.where("published = ? and expiration_date >= ?", true, Date.today).order("(featured and created_at > now() - interval '" + self.pinned_time_limit.to_s + " days') desc nulls last, created_at desc")
end

看着rails服务器,我看到缓存已读取,但是SQL查询仍然运行:

Looking at the rails server, I see the cache read, but the SQL Query still runs:

Cache read: views/#<ActiveRecord::Relation:0x007fbabef9cd58>/1-index 
Read fragment views/#<ActiveRecord::Relation:0x007fbabef9cd58>/1-index (1.0ms)
(0.6ms) SELECT COUNT(*) FROM "jobs" WHERE "jobs"."tenant_id" = 1 AND (published = 't' and expiration_date >= '2013-03-03')
  Job Load (1.2ms)  SELECT "jobs".* FROM "jobs" WHERE "jobs"."tenant_id" = 1 AND (published = 't' and expiration_date >= '2013-03-03') ORDER BY (featured and created_at > now() - interval '7 days') desc nulls last, created_at desc

关于我可能做错了什么的任何想法?我确定它必须与密钥生成和ActiveRecord :: Relation一起使用,但是我不确定该如何做.

Any ideas as to what I might be doing wrong? I'm sure it has to do w/ the key generation and ActiveRecord::Relation, but i'm not sure how.

推荐答案

我遇到了类似的问题,我无法成功将关系传递给缓存函数,并且您的@jobs变量是一个关系.

I have had similar problems, I have not been able to successfully pass relations to the cache function and your @jobs variable is a relation.

我为高速缓存密钥编写了一个解决方案,该解决方案可以解决这个问题以及其他一些问题.它基本上涉及通过迭代关系来生成缓存密钥.

I coded up a solution for cache keys that deals with this issue along with some others that I was having. It basically involves generating a cache key by iterating through the relation.

完整的文章在我的网站上.

A full write up is on my site here.

http://mark.stratmann.me/content_items/rails-caching-strategy-using-key-based-approach

总而言之,我向ActiveRecord :: Base添加了一个get_cache_keys函数

In summary I added a get_cache_keys function to ActiveRecord::Base

module CacheKeys
  extend ActiveSupport::Concern
  # Instance Methods
    def get_cache_key(prefix=nil)
      cache_key = []
      cache_key << prefix if prefix
      cache_key << self
      self.class.get_cache_key_children.each do |child|
        if child.macro == :has_many
          self.send(child.name).all.each do |child_record|
            cache_key << child_record.get_cache_key
          end
        end
        if child.macro == :belongs_to
          cache_key << self.send(child.name).get_cache_key
        end
      end
      return cache_key.flatten
    end

  # Class Methods
  module ClassMethods
    def cache_key_children(*args)
      @v_cache_key_children = []
      # validate the children
      args.each do |child|
        #is it an association
        association = reflect_on_association(child)
        if association == nil
          raise "#{child} is not an association!"
        end
        @v_cache_key_children << association
      end
    end

    def get_cache_key_children
      return @v_cache_key_children ||= []
    end

  end
end

# include the extension
ActiveRecord::Base.send(:include, CacheKeys)

我现在可以通过创建缓存片段

I can now create cache fragments by doing

cache(@model.get_cache_key(['textlabel'])) do

这篇关于Rails缓存密钥生成为ActiveRecord :: Relation的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆