To make a long question short: I'm fairly new to caching in Rails.
What's the best way to cache stuff that is used in the layout without
caching the entire action/view?
Lets say I have the following in my Application controller to set some
variables that are used in my layout:
before_filter :get_sidebar_items
def get_sidebar_items
@menu_items = MenuItem.all
@archives = Post.all_grouped_by_month
end
I can easily cache the display of the menu items in
application.html.erb using a fragment:
<% cache(:menu_items) do %>
<% for i in @menu_items %>
<%= i.name %>
<% end %>
<% end %>
Problem is, that doesn't cache the database query. Is there a nifty
way to cache some global stuff like this? As far as I can tell, the
Caching Guide doesn't touch on this much.
To make a long question short: I'm fairly new to caching in Rails.
What's the best way to cache stuff that is used in the layout without
caching the entire action/view?
Lets say I have the following in my Application controller to set some
variables that are used in my layout:
before_filter :get_sidebar_items
def get_sidebar_items
@menu_items = MenuItem.all
@archives = Post.all_grouped_by_month
end
I can easily cache the display of the menu items in
application.html.erb using a fragment:
<% cache(:menu_items) do %>
<% for i in @menu_items %>
<%= i.name %>
<% end %>
<% end %>
Problem is, that doesn't cache the database query. Is there a nifty
way to cache some global stuff like this? As far as I can tell, the
Caching Guide doesn't touch on this much.
Look up the RDoc for ActiveSupport::Cache::Store. You'll need to use
the interface described there (at least in Rails 2).
Although this is sort of wasteful if you're also fragment caching in
the view (wasteful in that you put data in the cache that you don't
use, and wasteful of one roundtrip to your memcache).
There isn't really a great way to say in rails "this code here only
exists to support this fragment in the view, so don't bother executing
it if you're just going to display the fragment from the cache
anyway".
In some cases wrapping the database access up in a helper can work,
but calling models straight from your helpers isn't particularly nice.
Another solution is the interlock plugin
Although this is sort of wasteful if you're also fragment caching in
the view (wasteful in that you put data in the cache that you don't
use, and wasteful of one roundtrip to your memcache).
But Memcached round trips are pretty cheap, since everything is in
memory.
There isn't really a great way to say in rails "this code here only
exists to support this fragment in the view, so don't bother executing
it if you're just going to display the fragment from the cache
anyway".
In some cases wrapping the database access up in a helper can work,
but calling models straight from your helpers isn't particularly nice.
I think DB access in a helper breaks MVC in most cases, because the
helper is really part of the view layer.
Concerns like this are contributing to a growing feeling on my part that
Rails-style MVC may be a mistake for certain types of complex Web
applications. The question is whether something better exists...
Note also that I am *not* advocating breaking MVC while using Rails.