Tutaj szuka się fragment caching, który występuje w warstwie widoku. Fragmentowanie pamięci podręcznej i wygaśnięcie przechowywanych treści jest zaskakująco łatwe. Masz listę książek, więc powiedzmy, że twój widok wygląda trochę tak:
<ul>
<% @books.each do |book| %>
<li><%= book.name %></li>
<% end %>
</ul>
Aby włączyć buforowanie tylko dla tego kawałka, po prostu zawinąć go w cache
:
<% cache do %>
<ul>
<% @books.each do |book| %>
<li><%= book.name %></li>
<% end %>
</ul>
<% end %>
Oczywiście, to nie nazywa pamięci podręcznej ani nie robi z nią nic specjalnego ... podczas gdy Railsy automatycznie wybierają unikalną nazwę tego fragmentu pamięci podręcznej, nie będzie to naprawdę pomocne. Możemy zrobić lepiej. Zastosujmy technikę DHH key-based cache expiration i nadaj pamięci podręcznej nazwę związaną z jej zawartością.
<% cache ['book-list', *@books] do %>
<ul>
<% @books.each do |book| %>
<li><%= book.name %></li>
<% end %>
</ul>
<% end %>
Przekazywanie argumentów do pamięci podręcznej cache buduje klucz z dostarczonych argumentów. Ciągi są przekazywane bezpośrednio - tak więc pamięć podręczna zawsze będzie poprzedzona "listą książek". Ma to na celu zapobieganie kolizjom pamięci podręcznej z innymi miejscami, w których buforowana jest ta sama treść, ale z innym widokiem. Dla każdego członka tablicy @books, Railsy wywołają cache_key
: dla obiektów ActiveRecord, to daje ciąg złożony z jego modelu, ID, i co najważniejsze, ostatnio, gdy obiekt został zaktualizowany.
Oznacza to, że po zaktualizowaniu obiektu klucz pamięci podręcznej dla tego fragmentu ulegnie zmianie. Innymi słowy, automatycznie wygasa - kiedy książka jest aktualizowana, ta instrukcja pamięci podręcznej wyszuka nieistniejący klucz, dojdzie do wniosku, że nie istnieje i zapełni go nową treścią. Stara, nieaktualna zawartość pozostanie w twoim magazynie pamięci podręcznej do czasu eksmisji z powodu ograniczeń związanych z pamięcią lub wiekiem (memcached robi to automatycznie).
Używam tej techniki w wielu aplikacjach produkcyjnych i działa wspaniale. Aby uzyskać więcej informacji, sprawdź, czy 37signals post i ogólne informacje o buforowaniu w Railsach, zobacz Ruby on Rails caching guide.
+1 na splatting kolekcję @books. Nigdy o tym nie pomyślałem, zwykle pobierałbym ostatnio zaktualizowany rekord książki w całej tabeli i używałam tego – cpuguy83
Powinieneś również buforować każdą książkę, aby jedna zmieniona książka nie przerwała całej pamięci podręcznej. – cpuguy83