Reputation: 617
I've never really delved into the amazing cache techniques Rails provides until now. One thing that I really can't wrap my head around is how to resolve a this particular problem.
Given that I have a Blog model with many Posts:
class Blog < ActiveRecord::Base
has_many :posts
end
class Post < ActiveRecord::Base
named_scope :published, :conditions => ["published_at < ?", Time.now]
end
And the show action in the BlogsController shows a list of Posts that have been published:
// BlogsController
def show
@blog = Blog.find(params[:id)
end
// View
<% @blog.posts.published.each do |p| %>
<h2><%=h p.title %></h2>
<%= simple_format(p.content) %>
<% end %>
The cache has to expire when any change is done to the published_at attribute BUT it also need to do it when published_at is put in the future and that time is reached.
Can you guys throw me some ideas and pointers of how to best solve this? Cron-job or am I loosing my mind?
Upvotes: 2
Views: 572
Reputation: 28332
It all depends on the kind of data store you're using to store the cache.
If you're using the filesystem you could write a cron job to invalidate the cache at a specific interval, or encode the datetime that the cache is valid until in the cachekey and check that on every request and invalidate when necessary.
Alternatively if you're backend if memcached you can use an expirable cache, which is probably the best solution.
Upvotes: 1
Reputation: 5498
The code you show doesn't use any of Rails' caching features. However your :published
named scope will use (and, in production, remember through class caching) Time.now
when that code is first executed.
I suspect you want this instead:
named_scope :published, lambda { { :conditions => ["published_at < ?", Time.now] } }
The lambda ensures that Rails re-evaluates your condition every time.
Upvotes: 5