You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails多行方法Memoize实现求助:首次接触该特性遇适用场景

在Rails中实现记忆化优化你的网络请求方法

嘿,刚好你的场景完美适配记忆化!每次调用manager_rep_code_and_name都发起一堆网络请求,确实会拖慢速度,用记忆化就能避免重复请求,直接复用之前的结果。我给你几种实用的实现方式:

方式一:记忆整个方法的返回值(最简单)

如果rep_code_list在实例生命周期内不会变化,直接用实例变量加||=就能搞定:

def manager_rep_code_and_name
  @manager ||= begin
    rep_code_list.map do |rep_code|
      context = Finfolio::GetManagerByRepCode.call(rep_code: rep_code)
      { name: context.manager.response.first["Name"], rep_code: rep_code }
    end
  end
end

我把你的push改成了map,代码更简洁~第一次调用方法时,会执行begin...end里的逻辑并把结果存到@manager里,之后再调用就直接返回缓存的结果,不会再发网络请求了。

方式二:按单个rep_code缓存(更灵活)

如果rep_code_list可能动态变化,或者同一个rep_code会多次出现在列表里,用哈希来缓存每个rep_code的结果更合适:

def manager_rep_code_and_name
  @manager_cache ||= {}
  rep_code_list.map do |rep_code|
    @manager_cache[rep_code] ||= begin
      context = Finfolio::GetManagerByRepCode.call(rep_code: rep_code)
      { name: context.manager.response.first["Name"], rep_code: rep_code }
    end
  end
end

这样每个rep_code只会发起一次网络请求,哪怕后续调用方法时列表里包含之前的rep_code,也直接用缓存好的数据,效率更高。

额外注意事项

  • 实例变量的缓存是绑定到实例的,每个实例的缓存独立,类方法的话可以用类变量或者@@,不过一般不推荐类变量,容易有线程安全问题。
  • 如果需要刷新缓存,比如manager的名字更新了,直接手动重置缓存即可:@manager = nil(对应方式一)或者@manager_cache.delete(rep_code)(对应方式二)。
  • 如果需要跨请求的缓存,那就要用Redis之类的外部缓存了,但如果只是优化单次请求内的重复调用,上面的实例变量方式完全够用。

内容的提问来源于stack exchange,提问作者Bitwise

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:02:43