<?xml version="1.0" encoding="UTF-8"?>
<code>
  <code># In one of your helper module, dump:
def cachable_time_ago_in_words(from)
  js_call = javascript_tag "document.write(DateHelper.timeAgoInWords(#{(from.to_i * 1000).to_json}) + ' ago');"
  "&lt;noscript&gt;on #{from.to_formatted_s(:long)}&lt;/noscript&gt;#{js_call}"
end

# In your application.js
var DateHelper = {
  timeAgoInWords: function(from) {
   return this.distanceOfTimeInWords(new Date().getTime(), from);
  },

  distanceOfTimeInWords: function(to, from) {
    seconds_ago = ((to  - from) / 1000);
    minutes_ago = Math.floor(seconds_ago / 60);

    if(minutes_ago == 0) { return "less than a minute"; }
    if(minutes_ago == 1) { return "a minute"; }
    if(minutes_ago &lt; 45) { return minutes_ago + " minutes"; }
    if(minutes_ago &lt; 90) { return " about 1 hour"; }
    hours_ago  = Math.round(minutes_ago / 60);
    if(minutes_ago &lt; 1440) { return "about " + hours_ago + " hours"; }
    if(minutes_ago &lt; 2880) { return "1 day"; }
    days_ago  = Math.round(minutes_ago / 1440);
    if(minutes_ago &lt; 43200) { return days_ago + " days"; }
    if(minutes_ago &lt; 86400) { return "about 1 month"; }
    months_ago  = Math.round(minutes_ago / 43200);
    if(minutes_ago &lt; 525960) { return months_ago + " months"; }
    if(minutes_ago &lt; 1051920) { return "about 1 year"; }
    years_ago  = Math.round(minutes_ago / 525960);
    return "over " + years_ago + " years";
  }
}

# Then in your views use:
&lt;%= cachable_time_ago_in_words Time.now %&gt;</code>
  <comment>When a page is cached, if you use the Rails ActionView helper "time_ago_in_words" the time will stay the same until the cache is refreshed, ie.: about 1 sec ago .... 1 hour later .... 1 sec ago.

Here's the solution in found at http://nullstyle.com/2007/6/3/caching-time_ago_in_words

Got any better solution ? Let me know !
</comment>
  <created-at type="datetime">2007-09-19T09:56:19+00:00</created-at>
  <id type="integer">7</id>
  <language>Ruby</language>
  <permalink>how-to-make-time_ago_in_words-cachable</permalink>
  <refactors-count type="integer">4</refactors-count>
  <title>How to make time_ago_in_words cachable ?</title>
  <trackback-url></trackback-url>
  <updated-at type="datetime">2008-04-10T21:54:08+00:00</updated-at>
  <user-id type="integer">1</user-id>
  <refactors type="array">
    <refactor>
      <code>def cachable_time_ago_in_words(from)
  if request.xhr?
    time_ago_in_words from
  else
    js_call = javascript_tag "document.write(DateHelper.timeAgoInWords(#{(from.to_i * 1000).to_json}) + ' ago');"
    "&lt;noscript&gt;on #{from.to_formatted_s(:long)}&lt;/noscript&gt;#{js_call}"
  end
end
</code>
      <code-id type="integer">7</code-id>
      <comment>Seems it doesn't work with AJAX request, here my solution, pretty simple
Thx James for reporting this!</comment>
      <created-at type="datetime">2007-09-19T13:16:10+00:00</created-at>
      <id type="integer">16</id>
      <language>Ruby</language>
      <rating type="integer">0</rating>
      <ratings-count type="integer">0</ratings-count>
      <title>On How to make time_ago_in_words cachable ?</title>
      <user-id type="integer">1</user-id>
      <user-name>macournoyer</user-name>
      <user-website>http://macournoyer.com</user-website>
    </refactor>
    <refactor>
      <code>def cachable_time_ago_in_words(from, id_prefix = '')
  id = "#{id_prefix}_#{from.to_i}"
  content_tag :span, "", :id =&gt; id
  javascript_tag "$('#{id}').update(DateHelper.timeAgoInWords(#{(from.to_i * 1000).to_json}))"
end</code>
      <code-id type="integer">7</code-id>
      <comment>But document.write is still gross, so here's my take</comment>
      <created-at type="datetime">2007-09-19T13:18:55+00:00</created-at>
      <id type="integer">17</id>
      <language>Ruby</language>
      <rating type="integer">4</rating>
      <ratings-count type="integer">1</ratings-count>
      <title>On How to make time_ago_in_words cachable ?</title>
      <user-id type="integer">2</user-id>
      <user-name>jamesgolick</user-name>
      <user-website>http://jamesgolick.com</user-website>
    </refactor>
    <refactor>
      <code>def cachable_time_ago_in_words(from, id_prefix = 'time_ago')
  id = "#{id_prefix}_#{from.to_i}"
  content_tag(:span, from.to_formatted_s(:long), :id =&gt; id) &lt;&lt;
  javascript_tag("$('#{id}').update(DateHelper.timeAgoInWords(#{(from.to_i * 1000).to_json}))")
end</code>
      <code-id type="integer">7</code-id>
      <comment>You're right, but this does not degrade gracefully and the first content_atg won't be rendered, here's my fix</comment>
      <created-at type="datetime">2007-09-19T13:29:18+00:00</created-at>
      <id type="integer">18</id>
      <language>Ruby</language>
      <rating type="integer">0</rating>
      <ratings-count type="integer">0</ratings-count>
      <title>On How to make time_ago_in_words cachable ?</title>
      <user-id type="integer">1</user-id>
      <user-name>macournoyer</user-name>
      <user-website>http://macournoyer.com</user-website>
    </refactor>
    <refactor>
      <code>distanceOfTimeInWords: function(to, from) {
  seconds_ago = ((to  - from) / 1000);
  minutes_ago = Math.floor(seconds_ago / 60);

  if(minutes_ago == 0) { return "less than a minute"; }
  if(minutes_ago == 1) { return "1 minute ago"; }
  if(minutes_ago &lt; 45) { return minutes_ago + " minutes"; }
  if(minutes_ago &lt; 90) { return " about 1 hour"; }
  hours_ago  = Math.floor(minutes_ago / 60);
  if(minutes_ago &lt; 1440) { return "about " + hours_ago + " hours"; }
  if(minutes_ago &lt; 2880) { return "1 day"; }
  days_ago  = Math.floor(minutes_ago / 1440);
  if(minutes_ago &lt; 43200) { return days_ago + " days"; }
  if(minutes_ago &lt; 86400) { return "about 1 month"; }
  months_ago  = Math.floor(minutes_ago / 43200);
  if(minutes_ago &lt; 525960) { return months_ago + " months"; }
  if(minutes_ago &lt; 1051920) { return "about 1 year"; }
  years_ago  = Math.floor(minutes_ago / 525960);
  return "over " + years_ago + " years";
}</code>
      <code-id type="integer">7</code-id>
      <comment>In the rails version the numbers are not cast to Floats before dividing, so the results are not consistent when you put this code and time_ago_in_words side by side. Using Math.floor will give the proper results.</comment>
      <created-at type="datetime">2008-04-10T21:54:08+00:00</created-at>
      <id type="integer">4820</id>
      <language>Ruby</language>
      <rating type="integer">0</rating>
      <ratings-count type="integer">0</ratings-count>
      <title>On How to make time_ago_in_words cachable ?</title>
      <user-id type="integer">547</user-id>
      <user-name>makenai</user-name>
      <user-website nil="true"></user-website>
    </refactor>
  </refactors>
</code>
