ruby on rails - Low level caching for collection -


i want use redis low level caching in rails app. in controller books:

class bookscontroller < applicationcontroller   def index     @books = book.order(:title)   end end 

and view iterates on this:

<ul>   - @books.each |book|     <li>= "#{book.title} - #{book.author}"</li> </ul> 

now want exact same result cached. have redis setup , running. should use cached_books method in controller this:

@books = book.cached_books.order(:title) 

and leave view is, or use book.cached_title , book.cached_author in view , leave controller is?

and how cached_books method in book model?

class book < activerecord::base   ...    def cached_books     rails.cache.fetch([self, "books"]) { books.to_a }   end end 

for simplicity sake leave out expire strategies now, need there.

so should use cached_books method in controller this:

yes, can. although there's gotchas have aware of. book activerecord. when call book.something (e.g. book.all, or book.order(:title) returns activerecord::relation, wrapper array of books (this wrapper prevents of firing unnecessary queries, boosting perfomance).

you can't save whole result of query in redis. say, can save json string of array of hashes model attributes, e.g.

[{   id: 1,   title: 'how make sandwich",   author: 'mr. cooker' }, {   id: 2,   title: 'london's bridge',   author: 'fergie' }] 

and can 'decrypt' thing array after. like

def cached_books(key)   # suggest native wrapper   if result = $redis.hget 'books_cache', key     result.map { |x| book.new(x) }   end end 

and also, have serialise attributes before putting them cache.

ok, have collections can iterated in view same data, although can't call order on cached collection, plain array (you may call sort, idea cache already sorted data).

well... worth it? actually, not really. if need cache piece – probably, best way cache rendered page, not query result.

should use cached_title , cached_author – that's question. first of all, depends on cached_title may be. if string – there's nothing can cache. book through db request, or book cache – in way title presented in it, simple type. let's closer author. going relation model author , place cache suits great. can re-define author method inside book (or define new , avoid nasty effects rails may have in complex queries in future) , see if there's cache. if yes, return cache. if not – query db, save result cache , return it.

def author   rails.cache.fetch("#{author_id}/info", expires_in: 12.hours)     # block executed if cache not founded     # it's better alias original method , call here     #instead of directly author.find call though     author.find(author_id)    end end 

or less convenient, more "safe":

def cached_author   rails.cache.fetch("#{author_id}/info", expires_in: 12.hours)     author   end end 

Comments

Popular posts from this blog

Magento/PHP - Get phones on all members in a customer group -

php - .htaccess mod_rewrite for dynamic url which has domain names -

Website Login Issue developed in magento -