Stai cercando fragment caching qui, che si verifica sul livello vista. Il caching dei frammenti e la scadenza dei contenuti memorizzati è sorprendentemente facile da fare. Si dispone di un elenco di libri, quindi diciamo che il vostro vista sembra un po 'come questo:
<ul>
<% @books.each do |book| %>
<li><%= book.name %></li>
<% end %>
</ul>
Per abilitare il caching proprio per questo po', basta avvolgerlo in cache
:
<% cache do %>
<ul>
<% @books.each do |book| %>
<li><%= book.name %></li>
<% end %>
</ul>
<% end %>
Naturalmente, questo non nomina il cache o fa qualcosa di veramente speciale con esso ... mentre Rails selezionerà automaticamente un nome univoco per questo frammento di cache, non sarà molto utile. Possiamo fare di meglio Usiamo la tecnica key-based cache expiration di DHH e forniamo alla cache un nome relativo al suo contenuto.
<% cache ['book-list', *@books] do %>
<ul>
<% @books.each do |book| %>
<li><%= book.name %></li>
<% end %>
</ul>
<% end %>
Passare argomenti nella cache crea la chiave di cache dagli argomenti forniti. Le stringhe vengono passate direttamente - quindi, qui, la cache sarà sempre preceduta da 'book-list'. Questo serve a prevenire collisioni nella cache con altri luoghi in cui è possibile memorizzare nella cache lo stesso contenuto, ma con una vista diversa. Per ogni membro dell'array @books, Rails chiamerà cache_key
: per gli oggetti ActiveRecord, questo produce una stringa composta dal suo modello, ID e, in modo cruciale, l'ultima volta che l'oggetto è stato aggiornato.
Ciò significa che quando si aggiorna l'oggetto, la chiave di cache per questo frammento cambierà. In altre parole, è automaticamente scaduto: quando un libro viene aggiornato, questa istruzione cache cerca una chiave inesistente, conclude che non esiste e la popola con nuovi contenuti. I contenuti vecchi e obsoleti rimarranno nel tuo archivio cache fino a quando non saranno sfrattati dalla memoria o dai limiti di età (memcached lo fa automaticamente).
Uso questa tecnica in numerose applicazioni di produzione e funziona meravigliosamente. Per ulteriori informazioni, controllare che 37signals post e per informazioni generali sulla memorizzazione nella cache in Rails, vedere Ruby on Rails caching guide.
+1 sul Splatting collezione @books. Non avrei mai pensato a questo, di solito prendevo il record del libro aggiornato più recentemente nell'intero tavolo e lo usavo. – cpuguy83
Dovresti anche mettere in cache ogni singolo libro in modo che un libro modificato non interrompa l'intera cache. – cpuguy83