Title: Memcached always miss (rails)
Tags: ruby-on-rails;ruby;memcached
Question: I have a class with this method:
def telecom_info
Rails.cache.fetch(&quot;telecom_info_for_#{ref_num}&quot;, :expires_in=&gt; 3.hours) do
info = Hash.new(0)
Telecom75b5:f2c1:f5d7:b954:8dc3:cee9:baf:a8c0SERVICES.each do |source|
results = TelecomUsage.find(:all,
:joins=&gt;[:telecom_invoice=&gt;{ :person=&gt; :org_person}],
:conditions=&gt;&quot;dotted_ids like '%#{ref_num}%' and telecom_usages.ruby_type = '#{source}'&quot;,
:select=&gt;&quot;avg(charge) #{source.upcase}_AVG_CHARGE,
max(charge) #{source.upcase}_MAX_CHARGE,
min(charge) #{source.upcase}_MIN_CHARGE,
sum(charge) #{source.upcase}_CHARGE,
avg(volume) #{source.upcase}_AVG_VOLUME,
max(volume) #{source.upcase}_MAX_VOLUME,
min(volume) #{source.upcase}_MIN_VOLUME,
sum(volume) #{source.upcase}_VOLUME
&quot;)
results = results.first
['charge', 'volume'].each do |source_type|
info[&quot;#{source}_#{source_type}&quot;.to_sym] = results.send(&quot;#{source}_#{source_type}&quot;.downcase).to_i
info[&quot;#{source}_min_#{source_type}&quot;.to_sym] = results.send(&quot;#{source}_min_#{source_type}&quot;.downcase).to_i
info[&quot;#{source}_max_#{source_type}&quot;.to_sym] = results.send(&quot;#{source}_max_#{source_type}&quot;.downcase).to_i
info[&quot;#{source}_avg_#{source_type}&quot;.to_sym] = results.send(&quot;#{source}_avg_#{source_type}&quot;.downcase).to_i
end
end

return info
end
As you can see, this is an expensive call, and it is called ALOT for each request so I want to cache it. The problem is that memcached does not seem to work, in the log file, I am getting:
Cache read: telecom_info_for_60000000
Cache miss: telecom_info_for_60000000 ({})
The weird thing is that I know memcached is working since it does cache the results of some other functions I have in another model.
Any suggestions? I am running Rails 2.3.5 on REE 1.8.7
Comment: Didn't know there was a kind of flower called a stackover. Har har har.

Here is the accepted answer: Replace return info with info.
Rails.cache.fetch("telecom_info_for_#{ref_num}", :expires_in=&gt; 3.hours) do
# ...
info
The return keyword always returns from the current method, which means that info is never returned to your call to Rails.cache.fetch, nor is the rest of that method ever executed. When the last statement simply is info, this is the value that will be given to Rails.cache.fetch, and you will allow the method to finish its duty by storing this value in the cache.
Compare the following:
def my_method
1.upto(3) do |i|
# Calling return immediately causes Ruby to exit the current method.
return i
my_method
#=&gt; 1
As a rule of thumb: always omit return unless you really mean to exit the current block and return from the current method.


{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 1, 'CommentCount': 1, 'ContentLicense': 'CC BY-SA 4.0', 'CreationDate': '2010:00:09/03/10', 'FavoriteCount': 1.0, 'PostTypeId': 1, 'Tags': '<ruby-on-rails><ruby><memcached>', 'Title': 'Memcached always miss (rails)', 'ViewCount': 618, 'id': 3636872, 'user_AboutMe': None, 'user_AccountId': 147418.0, 'user_DisplayName': 'Alain', 'user_Reputation': 1201.0, 'user_Views': 95.0, 'user_id': 358524.0}}