Ryan: Thanks for another GREAT 'cast. You inspire me to write great code.

Please help to understand: I thought database calls were meant to be in the controller. I understand moving logic to the model, but I thought it was more appropriate to keep calls out of the view and in the controller. Am I wrong here or is best to keep calls in the controller unless the fragment is cached?

@Bryce, many developers don't like calling model finds directly from the view, but I usually don't have a problem with it. IMO views have as much access to models as controllers do in MVC.

But then you could say what's stopping the view from taking over the controllers role and doing all model processing? It's important to understand the role of a controller.

Don't think of the controller as a layer between the view and the model, instead think of it as a layer between the user and the application. The controller should process user input and filter that to the models and views. Many times this involves taking the params hash and fetching models for the view.

Notice in this case the @recent_products array had nothing to do with user input. Therefore it belongs in the view more than the controller. Why should the controller care that we want to display the recent products in addition to what the user requested?

I would have a much harder time moving the @product find itself into the view because this comes from the user input (params hash) and is directly what the user requested.

This is all my own theory. Other developers think differently so I encourage you to find what works best for you.

@chris, great question. Unfortunately I don't know the answer as I don't test caching. I imagine you will have to enable caching temporarily in your testing environment and check for the existance of the file. Alternatively you could use mocking and just make sure youre view calls the cache method with the proper parameters.

Great screencast - things worked without a flaw on my development machine and the cached partials are stored in /tmp/cache directory. I noticed, however, on the production machine that neither the cached partials nor the /tmp/cache directory exist - am I missing something or are my partials not getting cached? Thanks.

p.s. I have this line in environments/production.rb: config.action_controller.perform_caching = true so I believe caching is turned on.

@sthapit, there are various places the cache could be stored. In development mode this defaults to a file store, but in production it defaults to a memory store. If you have a mongrel cluster then memory store probably isn't the best because it will need to be cached separately for each mongrel process and memory could get out of hand. Instead I recommend starting with a file based store by adding this line to your production.rb file:

that makes perfect sense. yes, i'm using a mongrel cluster so i added that to production.rb and /tmp/cache now stores all the cached partials.

i'd also noticed that without that line the cached partial wouldn't expire with the sweeper consistently - but i think it makes sense now. it was probably not getting refreshed on all mongrels. but now that problem is gone as well. thanks!

I've got a messages controller (and a message Model), an different methods among which index, unread, flagged... etc that performs different Message.find(...) but render messages in the same way, with a "respond_to", for each type of call (HTL, XML, or AJAX).

Should I put all the logic in the partial, within the cache block? It seems pretty awkward to do a case params[:action] in my view... and keeping index unread, flagged actions empty in my controller!

In my project, there are many accounts. Each account has many users, but the fragments can be cached for all the users in an account, so putting the account id in the cache identifier is enough to make them unique.

Very nice presentation (on a subject that usually is so soporific). I had only a doubt on the view issuing a call to the model (that I had never seen in Rails).

I then saw the answer given by Ryan (post #10): "the @recent_products array had nothing to do with user input. Therefore it belongs in the view more than the controller. Why should the controller care that we want to display the recent products in addition to what the user requested?".

What's the best way to cache the individual records in a render like this:

render :xml => @products.to_xml

I'm caching the entire render with action caching, but when I expire the action, I shouldn't have to re-render each individual product's XML, possibly including deep associations. Is there a way without throwing it all into the views and fragment caching there?