2012-12-03 24 views
6

Sayfanın her tarafında bazı kısmi olarak işlenen bir ana sayfam var.Ayrıca oturum üstbilgisi de var (giriş). Kısmi, paginated olan kitap kümesini içerir. Şimdi haftada bir kez güncellenen bu kısmi önbelleğe almak istiyorum.Belirli kısmi rayları önbelleğe alma 3.0.x

  • Soru 1: Bu kısmi önbelleği nasıl önbelleğe alırım ( db yerine)?
  • Soru 2: Kitap modeli 'u güncelleştirdiğimde önbelleğe alınan içeriği nasıl silebilirim (sona erdirir)?

cevap

8

Burada görünüm katmanında oluşan fragment caching'u arıyorsunuz. Parçalanmış önbelleğe alma ve depolanan içeriklerin sona ermesi şaşırtıcı derecede kolaydır. Bu Tabii

<% cache do %> 
    <ul> 
    <% @books.each do |book| %> 
     <li><%= book.name %></li> 
    <% end %> 
    </ul> 
<% end %> 

: Sen kitap listesi var, bu yüzden senin görünümü böyle biraz görünüyor diyelim:

<ul> 
    <% @books.each do |book| %> 
    <li><%= book.name %></li> 
    <% end %> 
</ul> 

basitçe cache alanına kaydırmak sadece bu biraz önbelleğe etkinleştirmek için Önbelleğe isim vermez ya da onunla gerçekten özel bir şey yapmaz ... Rails bu önbellek parçacığı için otomatik olarak benzersiz bir isim seçerse, gerçekten yardımcı olmaz. Daha iyisini yapabiliriz. DHH'nin key-based cache expiration tekniğini kullanalım ve önbelleğe içeriğiyle ilgili bir isim verelim.

Argümanların önbelleğe geçirilmesi, sağlanan argümanlardan önbellek anahtarını oluşturur. Dizeler doğrudan iletilir - burada, önbellek her zaman 'kitap listesi' ile başlatılacaktır. Bu, önbellek çakışmalarının, aynı içeriği önbelleğe alabileceğiniz başka yerler ile, ancak farklı bir görünümle engellenmesidir. @books dizisinin her bir üyesi için Rails, ActiveRecord nesneleri için cache_key'u arayacaktır: Bu, nesnesinin son güncellendiği zaman, modelinden ve kimliğinden oluşan bir dize verir.

Bu, nesneyi güncelleştirdiğinizde, bu bölümün önbellek anahtarının değişeceği anlamına gelir. Diğer bir deyişle, otomatik olarak geçerlilik süresi sona ermektedir - bir kitap güncellendiğinde, bu önbellek bildirimi varolmayan bir anahtar arayacak, var olmadığı sonucuna varacak ve yeni içerikle doldurulacaktır. Eski, eski içerik, bellek ya da yaş kısıtlamaları tarafından tahliye edilene kadar önbellek deposunuzda durur (bu işlem otomatik olarak yapılır).

Bu tekniği bir dizi üretim uygulamasında kullanıyorum ve harika çalışıyor. Daha fazla bilgi için, 37signals post ve Raylar'daki genel önbellek bilgileri için Ruby on Rails caching guide'a bakın.

+0

+1 @books koleksiyonunu splatting üzerinde. Bunu hiç düşünmemiştim, genellikle tüm tablodaki en son güncellenen kitap kaydını alıp – cpuguy83

+0

kullanın. Ayrıca her bir kitabı da değiştirmelisiniz, böylece değiştirilen bir kitap tüm önbelleği kırmaz. – cpuguy83

4

"Bilgisayar Bilimleri sadece iki sert sorun vardır. önbellekte geçersiz kılma ve adlandırma şeyler"
- Phil Karlton


Rails Guide to caching Caching muhtemelen her zaman sunmaya gelmiştir önbelleğe alma stratejileri raylar inşa için iyi bir giriş noktasıdır.Neyse burada

# _partial.html.erb 
<% cache(some_key, :expires_in => 1.week) do %> 
    <%# ... content %> 
<% end %> 

Şimdi bazı some_key sürece benzersiz olduğu gibi herhangi bir dize olabilir önbelleğe

benim çok kolay bir yaklaşım geliyor. Ama sonra yine bu konuda biraz daha zeki olmaya çalışın ve bir şekilde kitapların bir şekilde listesine girmesini sağlayın. Gerçekte books dizisinin içinden geçtiğinizi söyleyin, böylece bazı girdiler cache_key numaralarını çağırır ve sonunda bu koleksiyon için benzersiz bir anahtar oluşturur. Böylece koleksiyon anahtar değişikliklerini değiştirdiğinde. cache_key, ActiveRecord::Base'da uygulandığı için tüm Modellerde kullanılabilir. Dahası, eğer varsa, zaman damgalarını da kullanır.

Fakat sonra tekrar bu bir istek yapıldığında db nu gösterir. kodunda aynı:

# controller_method 
@weekly_books = Books.where 'condition' 

# _partial.html.erb 
<% cache(@weekly_books) do %> 
    <%# ... content %> 
<% end %> 

sıklıkla da çağrıyı sararak sorgu kendi kendini önbelleğe alabilir için db çarpmamak için:

# Book.rb 
def self.weeklies 
    Rails.cache.fetch("book_weeklies", :expires_in => 1.day) do 
    Books.where 'condition' 
    end 
end 

# controller_method 
@weekly_books = Books.weeklies 

# _partial.html.erb 
<% cache(@weekly_books) do %> 
    <%# ... content %> 
<% end %> 
+0

Sorun, ana sayfamda Kitaplar paginated. Parçalı kitaplara kısmi olarak yolluyorum. Şimdi Books.weeklies kullanırsam, bu paginated kayıtları vermez. Bunu nasıl başarabilirim? –

İlgili konular