新手问题 Rails.cache.fetch 的外层方法不能有参数么?我有参数的外层方法内部的缓存都没有执行

imwildcat · 2017年06月22日 · 最后由 imwildcat 回复于 2017年06月23日 · 2383 次阅读

以钉钉 API 调用举个例子(js ticket 需要缓存):

def get_js_ticket_1(access_token)
  Rails.logger.info 'fetching dingding js ticket'
  res = Net::HTTP.get(URI.parse("https://oapi.dingtalk.com/get_jsapi_ticket?access_token=#{access_token}"))
  if res
    result = ActiveSupport::JSON.decode(res)
    p result
    if result and result['errcode'] == 0
      return result['ticket']
    end
  end
  raise 'Cannot get access token for Dingding'
end

def get_cached_js_ticket
  Rails.cache.fetch('dingding_js_t', expires_in: 1.hour) do
    ak = get_access_token
    get_js_ticket_1(ak)
  end
end

这里get_cached_js_ticket没有参数的,可以正确执行缓存。

但是:

def get_js_ticket_2(access_token)
  Rails.cache.fetch('dingding_js_t', expires_in: 1.hour) do
    Rails.logger.info 'fetching dingding js ticket'
    res = Net::HTTP.get(URI.parse("https://oapi.dingtalk.com/get_jsapi_ticket?access_token=#{access_token}"))
    if res
      result = ActiveSupport::JSON.decode(res)
      p result
      if result and result['errcode'] == 0
        return result['ticket']
      end
    end
    raise 'Cannot get access token for Dingding'
  end
end

则不能成功缓存。

感觉好黑科技啊,内层的方法如何检测外层方法有没有参数?怎么实现的?

get_cached_js_ticket 调用的时候用了 dingding_js_t 作 key,之后在里面又调用了 get_js_ticket,get_js_ticket 里面又用 dingding_js_t 作 key,所以 get_js_ticket 里面缓存的代码永远不会被执行

wootaw 回复

实际情况是 如果把上面的代码删了,下面那段代码中 get_js_ticket 缓存内部的代码每次都会被执行,而且缓存里查不到。

为了防止混淆我改个名字,上面的 get_js_ticket 改为 get_js_ticket_1, 下面的 get_js_ticket 改为 get_js_ticket_2

imwildcat 关闭了讨论。 06月22日 10:43
imwildcat 重新开启了讨论。 06月22日 10:43

你需要把 access_token 放在 cache key 当中

teddyinfi 回复

嗯!是的,但是能否给点参考,内部方法是如何检测外部方法的实现的?

内部方法是如何检测外部方法的实现的?

楼主,我不知道怎么答你,因为问题都提错了。你应该问:

我执行 1 的时候得到结果 X,执行 2 的时候得到结果 Y,而我预期的是 Z,为什么跟我预期的不一样。

  1. 大致看懂了你的问题,跟参数无关,跟你的 return 有关,不要在 ruby 里面写 return,不要在 ruby 里面写 return,不要在 ruby 里面写 return......

  2. 要找点时间去了解下 block, proc, lambda, 这个就是 return 在这三者里有不同的效果导致的。(元编程里有一节讲这三者的,你可以找下,我语拙就不解释了)

Rei 回复

原谅我的表达能力, 我的问题是:

我执行 1 的时候得到结果 X,执行 2 的时候得到结果 Y,而我预期的是 X,为什么跟我预期的不一样:为什么 2 的结果不是 X

flingfox63 回复

万谢!

imwildcat 关闭了讨论。 06月23日 14:14
需要 登录 后方可回复, 如果你还没有账号请 注册新账号