【问题标题】:Lazy loading / caching Ruby model attributes?延迟加载/缓存 Ruby 模型属性?
【发布时间】:2014-04-12 04:39:52
【问题描述】:

我将用户会话密钥存储在 Rails 活动记录模型中名为 skey 的列中。 skey 必须通过外部 API 调用每 10 分钟获取一次,但在 10 分钟过去之前,我想缓存 skey 并返回缓存的值。这是我得到的:

def skey_valid?
  (Time.now - self.skey_used_at) < 7.minutes
end

def skey
  if skey_valid? == false
    _skey = authenticate #external API call
    if _skey.nil?
      return nil
    end

    update_attribute :skey, _skey
  end

  update_attribute :skey_used_at, Time.now
  return self[:skey]
end

现在的问题是当我调用 User.skey 时,它进入了一个无限循环并且堆栈溢出。显然,当我执行 update_attribute :skey, _skey 时,我的自定义 skey 函数被调用,该函数再次调用 update_attribute :skey, _skey。

关于如何解决这个问题的任何建议?或者,如果有更好的方法来解决我正在尝试做的事情,我很想知道。谢谢。

【问题讨论】:

  • 顺便说一句,我维护了一个名为 volatile_hash 的 gem,它对哈希执行类似的操作。

标签: ruby-on-rails caching activerecord lazy-loading


【解决方案1】:

使用update_columns 而不是update_attribute。更新会直接发出更新查询,而不是使用getter

def skey_valid?
  (Time.now - self.skey_used_at) < 7.minutes
end

def skey
  unless skey_valid?
    _skey = authenticate #external API call
    return nil unless _skey

    update_columns(:skey => _skey)
  end

  update_columns(:skey_used_at => Time.now)
  return read_attribute(:skey)
end

【讨论】:

  • 使用您发布的确切代码的 update(:skey => _skey) 似乎也发生了同样的问题。如果这很重要,我正在使用 Rails 4.0.0。
  • 修改了我的答案。我应该测试过它。很抱歉
猜你喜欢
  • 2019-08-28
  • 2012-03-12
  • 2017-12-28
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 2013-07-03
相关资源
最近更新 更多