Ruby on rails 自定义Rails缓存和关联-覆盖ActiveRecord.find

Ruby on rails 自定义Rails缓存和关联-覆盖ActiveRecord.find,ruby-on-rails,Ruby On Rails,我想写一个定制的ActiveRecord缓存,现在只用于find\u by\u id。 为此,我希望覆盖find方法,当只给出一个int时,使用我的缓存,否则使用默认实现 class X < ActiveRecord::Base def self.find(*args) return XCache[args[0]] if args.size == 1 && args[0].is_a?(Numeric) return super.fin

我想写一个定制的ActiveRecord缓存,现在只用于
find\u by\u id
。 为此,我希望覆盖find方法,当只给出一个int时,使用我的缓存,否则使用默认实现

class X < ActiveRecord::Base
    def self.find(*args)
        return XCache[args[0]] if args.size == 1 && args[0].is_a?(Numeric)
        return super.find(*args)
    end
end
当我调用
X.find(1).children
时,我得到的是一个
枚举数,而不是
数组,这很糟糕,因为我有时使用[]运算符

即使使用枚举器也不能很好地工作-在迭代我得到的最后一个条目时:

NoMethodError: undefined method `call' for :all:Symbol
任何帮助都将不胜感激

进一步解释:

XCache只是一个缓存ActiveRecord实例的类。 一个过于简单的实现可以是

class XCache
    @@cache = {}
    def self.[id]
        return @@cache[id] ||= X.find(id)
    end
end
(更高级的实现可以包括过期时间、Memcached等,更通用的解决方案可以支持多个模型类)


我不认为我的问题与缓存实现有关(但我可能错了)

不确定它是否有帮助,但。。。这是find内部的外观:

  def find(*args)
    options = args.extract_options!
    validate_find_options(options)
    set_readonly_option!(options)

    case args.first
      when :first then find_initial(options)
      when :last  then find_last(options)
      when :all   then find_every(options)
      else             find_from_ids(args, options)
    end
  end
您不需要重载“find”,而是“find\u from\u id”

这将使您不必考虑使用find的所有其他方法,只需针对您自己的使用。。。这可能有助于你的处境(也可能没有)

另一种可能性是。。。Xcache是否只返回单个ActiveRecord,或者是否可能有时返回一个集合。。。甚至是一套空的

也许您可以尝试以下方面的变化:

def self.find(*args)
    if args.size == 1 && args[0].is_a?(Numeric)
       rval = XCache[args[0]]
       return rval if rval.present?
    end
    super.find(*args)
end

正如你所看到的,这里有很多隐藏的复杂性。你可以看看宝石,这些家伙花了很多精力来弄清楚


其他需要注意的要点:

您希望在这里实现什么目标?通用库或特定问题的解决方案?您能解释一下
XCache
是什么吗?我在网上搜索,但什么也没找到。如果你自己实现了(如果不是太多代码),只需将代码添加到你的问题中
def self.find(*args)
    if args.size == 1 && args[0].is_a?(Numeric)
       rval = XCache[args[0]]
       return rval if rval.present?
    end
    super.find(*args)
end