I have a question here: how much expiring cache is supposed to be tight to the model? Is really a good idea to have models or even controllers generally aware of what needs to be expired?
Here it's ok to couple caching with model since retrieve the "most recent posts" is a business domain feature:
class Post
class << self
def most_recent_posts
Rails.cache.fetch ...
end
end
# ...
end
using an observer or decorator here is also fine to create a separate layer that adds caching behavior. Sweepers are better when we need to control cache at controller/application logic level (page/action/requests ..).
But in this second snippet it's not ok to have the model/controller knowing what needs to be expired since it's something only related to views:
# inside Post or PostSweper
after_create
expire_fragment: "list_of_the_most_recent_posts"
---
<%= cache("list_of_the_most_recent_posts") do %>
<ul>
...
</ul>
<% end %>
Also, to be more pragmatic, as the application grows we could have a lot of fragments and it could be not so simple to manage them with sweepers as they are.
We have to remember what to expire and also to delete expiration code when it is used no more, but also the same fragment can be fetched across multiple views, and so we've to check this with 'grep -R "fragment_key"' ./views' ... growing our apps makes things get too complicated ... not good.
So wouldn't this (or something like this) be better?
<%= cache("a_fragment", :expire_when => :something_happens) do %>
...
<% end %>
and just say: "ok, done to cache this part of the page".
It would be ok to have a sort of Observer to define the 'something_happens' part.