2008年7月27日日曜日

rubyでキャッシュ: 例えばrailsのActiveRecordクエリの結果をキャッシュするとか

例えば外部のAPIを叩いたり、データベースの重たい処理をする時など、キャッシュを上手く使った方がいいよねってことで、PHPでモノを作る時にはPEARのCache_LiteとかZend FrameworkのZend_Cacheなどを駆使してきました。Cache_LiteもZend_Cacheもserialize関数,unserialize関数を使って、シリアライズされた配列やオブジェクトをファイルに書き出したり読み戻しています。

ruby、というかrailsでキャッシュしたい時には、これまでrails付属のキャッシュシステム(主にfragmentキャッシュ)を利用してきましたが、railsのキャッシュは出力されるHTMLなどを保存するものですよね。
rubyで文字列やハッシュをキャッシュしたい時にはどうすればいいんだろうと調べていたら、Marshalというモジュールが使えるようです。

Marshal - Rubyリファレンスマニュアル

具体的な例としてActiveRecordクエリの結果をキャッシュするコード

Marshalize (Cache) ActiveRecord Query Results
(http://snippets.dzone.com)

class MyCachedModel < ActiveRecord::Base
class << self
alias_method :rails_original_find_by_sql, :find_by_sql
def find_by_sql(sql)
cache_filename = Base64.encode64(sql)
if File.exists? cache_filename
Marshal.load(File.open(cache_filename))
else
Marshal.dump(records = rails_original_find_by_sql(sql), File.open(cache_filename, 'w'))
return records
end
end
end
end


ファイルがあればMarshal.loadで読み戻し、なければMarshal.dumpで書き出しています。

0 件のコメント: