2012-12-03 13 views
6

मेरे पास एक होम पेज है जिसमें पूरे पृष्ठ पर कुछ आंशिक रूप से प्रस्तुत किया गया है। और इसमें सत्र शीर्षलेख भी है (लॉगिन)। आंशिक पुस्तकें अंकित पुस्तकें सेट हैं। अब मैं इस आंशिक को कैश करना चाहता हूं क्योंकि यह एक सप्ताह में एक बार अपडेट हो रहा है।कैशिंग विशेष आंशिक रेल 3.0.x

  • प्रश्न 1: मैं उस विशेष आंशिक कैश कैसे करूं ( डीबी मारने के बिना)?
  • प्रश्न 2: जब मैं पुस्तकें मॉडल अद्यतन करता हूं तो मैं कैश की गई सामग्री को कैसे समाप्त करूं?

उत्तर

8

आप यहां देखें fragment caching, जो दृश्य परत पर होता है। फ्रैगमेंट कैशिंग और संग्रहीत सामग्री की समाप्ति आश्चर्यजनक रूप से करना आसान है। आप पुस्तकों की एक सूची है, तो मान लीजिए कि आपके विचार इस तरह एक सा लग रहा है:

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

सिर्फ इस बिट के लिए कैशिंग को सक्षम करने के लिए बस cache में लपेट:

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

, इस कैश का नाम नहीं है या इसके साथ वास्तव में कुछ भी विशेष नहीं है ... जबकि रेल इस कैश खंड के लिए एक अद्वितीय नाम स्वतः चयन करेंगे, यह वास्तव में सहायक नहीं होगा। हम बेहतर कर सकते हैं। आइए डीएचएच की key-based cache expiration तकनीक का उपयोग करें और कैश को अपनी सामग्री से संबंधित नाम दें।

<% cache ['book-list', *@books] do %> 
    <ul> 
    <% @books.each do |book| %> 
     <li><%= book.name %></li> 
    <% end %> 
    </ul> 
<% end %> 

कैश में तर्क पास करने से आपूर्ति किए गए तर्कों से कैश कुंजी बनती है। स्ट्रिंग सीधे में पारित की जाती हैं - इसलिए, यहां, कैश हमेशा 'पुस्तक-सूची' से पहले रखा जाएगा। यह उन स्थानों के साथ कैश टकराव को रोकने के लिए है जो आप एक ही सामग्री को कैश कर सकते हैं, लेकिन एक अलग दृश्य के साथ। @books सरणी के प्रत्येक सदस्य के लिए, रेल cache_key पर कॉल करेंगे: ActiveRecord ऑब्जेक्ट्स के लिए, यह ऑब्जेक्ट अपडेट होने पर आखिरी बार अपने मॉडल, आईडी और महत्वपूर्ण रूप से बना एक स्ट्रिंग उत्पन्न करता है।

इसका मतलब है कि जब आप ऑब्जेक्ट को अपडेट करते हैं, तो इस खंड के लिए कैश कुंजी बदल जाएगी। दूसरे शब्दों में, यह स्वचालित रूप से समाप्त हो जाता है - जब कोई पुस्तक अपडेट की जाती है, तो यह कैश स्टेटमेंट एक अनन्य कुंजी की खोज करेगा, निष्कर्ष निकाला है कि यह अस्तित्व में नहीं है, और इसे नई सामग्री के साथ पॉप्युलेट करता है। पुरानी, ​​पुरानी सामग्री आपके कैश स्टोर में रहती है जब तक कि स्मृति या आयु बाधाओं से बेदखल न हो जाए (memcached यह स्वचालित रूप से करता है)।

मैं इस तकनीक का उपयोग कई उत्पादन अनुप्रयोगों में करता हूं और यह अद्भुत काम करता है। अधिक जानकारी के लिए, 37signals post देखें, और रेल में सामान्य कैशिंग जानकारी के लिए, Ruby on Rails caching guide देखें।

+0

+1:

# controller_method @weekly_books = Books.where 'condition' # _partial.html.erb <% cache(@weekly_books) do %> <%# ... content %> <% end %> 

db मार अक्सर आप भी क्वेरी कॉल लपेटकर द्वारा अपने स्वयं के कैश कर सकते करने के लिए से बचने के लिए। इस बारे में कभी सोचा नहीं, मैं आमतौर पर पूरी तालिका में सबसे हाल ही में अपडेट किए गए पुस्तक रिकॉर्ड को पकड़ लेता हूं और – cpuguy83

+0

का उपयोग करता हूं आपको प्रत्येक व्यक्तिगत पुस्तक को भी कैशिंग करना चाहिए ताकि एक बदली हुई पुस्तक पूरे कैश को तोड़ न दे। – cpuguy83

4

"कंप्यूटर विज्ञान में केवल दो कठोर समस्याएं हैं: कैश अमान्यता और नामकरण चीजें।"
- फिल Karlton

कैशिंग


Rails Guide to caching शायद हमेशा कैशिंग रणनीति पटरियों में बनाया के लिए एक अच्छा प्रवेश बिंदु की पेशकश करने गया है।वैसे भी यहाँ कैशिंग

करने के लिए अपने बहुत ही आसान दृष्टिकोण आता
# _partial.html.erb 
<% cache(some_key, :expires_in => 1.week) do %> 
    <%# ... content %> 
<% end %> 

अब कुछ some_key जब तक कि यह अद्वितीय है के रूप में किसी भी स्ट्रिंग हो सकता है। लेकिन फिर फिर से इसके बारे में थोड़ा अधिक चालाक होने की कोशिश करें और किताबों की सूची पर किसी भी तरह की कुंजी को कुंजी बना दें। मान लें कि आप वास्तव में books की सरणी में पास हो गए हैं, फिर कुछ क्वेरी लौटा दी गई है, फिर रेलवे अपनी प्रत्येक प्रविष्टि पर cache_key पर कॉल करती है और अंततः इस संग्रह के लिए एक अनूठी कुंजी बनाती है। तो जब संग्रह महत्वपूर्ण परिवर्तनों को बदल देता है। Thats क्योंकि cache_keyActiveRecord::Base में लागू किया गया है और इस प्रकार सभी मॉडल पर उपलब्ध है। और यदि उपलब्ध हो तो यह टाइमस्टैम्प का भी उपयोग करता है।

लेकिन फिर यह अनुरोध हर बार डीबी पर होगा। कोड में एक ही: @books संग्रह splatting पर

# 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

समस्या मेरे होम पेज में है पृष्ठ पुस्तकें अंकनित हैं। मैं भाग्यशाली किताबों को आंशिक रूप से भेजता हूं। अब अगर मैं Books.weeklies का उपयोग करता हूं, तो यह पेजिनेटेड रिकॉर्ड नहीं देगा। इसे कैसे प्राप्त करें? –