Reputation: 455
I'm storing user session keys in a Rails active record model in a column called skey. skey must be obtained every 10 minutes via an external API call, but until 10 minutes have elapsed I'd like to cache skey and return the cached value. Here's what I've got:
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
The problem is now when I call User.skey, it enters an infinite loop and stack overflows. Apparently when I execute update_attribute :skey, _skey, my custom skey function is called which again calls update_attribute :skey, _skey.
Any suggestions on how to get around this? Or if there's a better to approach to what I'm trying to do I'd love to know. Thanks.
Upvotes: 0
Views: 363
Reputation: 29349
use update_columns
instead of update_attribute
. Update will directly issue update query instead of using the 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
Upvotes: 2