Ruby言語やLinuxのネタが多いです。
July 05, 2007 [おもひで]
■ [Rails] Ruby-GetText+Railsのキャッシュ
rubyonrails-talkでRuby-GetTextでキャッシュってどうやるの?という質問があった。そういえば、この質問、過去にも何回かあったなぁ、と思ってちょっと見てみたら、Page/Action/Fragmentの各キャッシュのうち、Action/Fragmentについてはあっさりと対応できることがわかった。具体的には以下のコードをどこかしら(プラグインやapplicaton.rbあたり)に追加すればOK。
module ActionController
module Caching
module Fragments
def fragment_cache_key_with_gettext(name)
fragment_cache_key_without_gettext(name).gsub('?', '.').gsub(/:/, ".") << "_#{Locale.current}"
end
alias_method_chain :fragment_cache_key, :gettext
def expire_fragment_with_gettext(name, options = nil)
return unless perform_caching
key = %r{#{fragment_cache_key_without_gettext(name).gsub('?', '.').gsub(/:/, ".")}}
self.class.benchmark "Expired fragments matching: #{key.source}" do
fragment_cache_store.delete_matched(key, options)
end
end
alias_method_chain :expire_fragment, :gettext
end
end
end
上記はFragmentキャッシュの実装なんだけど、実はActionの方もこちらを呼んでるのでこれだけでよいはず。
使い方はRails本体とまったく変わらないけど軽く説明しておこう。念のため言っておくけど、この例ではArticleというモデルを利用している。あ、そうそう、init_gettextとか、Ruby-GetTextの諸々の設定は先に済ませておくように。
# app/controller/articles_controller.rb
class ArticlesController < ApplicationController
caches_action :show #showのアクションをキャッシュ
:
:
def show
@article = Article.find(params[:id])
end
#とりあえずcreate時にキャッシュをクリアする。
def create
@article = Article.new(params[:article])
if @article.save
expire_fragment(:action => "list") #Flagmentキャッシュをクリア
expire_action(:action => "show") #Actionキャッシュをクリア
:
:
end
# app/views/articles/list.rhtml <h1>Listing articles</h1> <% cache do %> これ以降がキャッシュされる : : <table> : : </table> : : <% end %> ここまで
要はまったくGetTextを意識する必要がなく、オリジナルのRailsの意識のままで使うことが出来る。ステキ。
■ Pageキャッシュが最強なのは言うまでもないんだけど、こちらは難しそうなのでちょっと棚上げ。でも、Scaffold直後(+GetText化済み)の10レコードくらいのサンプルアプリケーションの一覧表示でも、Actionキャッシュは2.4倍, Fragmentキャッシュは、1.5倍程度高速化できたので、ちょっと複雑なビジネスロジック、DBアクセスがあればもっと高い効果があるはず。
■ 思いもかけず簡単に実装できてしまったのでちょっと不安も残るけど、せっかくのなのでこの機能を次バージョンのRuby-GetTextに含める予定。
ひとまず、どなたか追試してみません?
■ [Rails] Ruby-GetText+Railsのキャッシュ(2)
もうちょっとだけ。キャッシュが実際に効いてるかどうかを目で見るには、キャッシュファイルが作成されたり削除されたりを確認するのが手っ取り早い。で、config/environment.rbの一番下に以下の記述を追加。
ActionController::Base.fragment_cache_store =
ActionController::Caching::Fragments::FileStore.new("/home/mutoh/rails/cache/")
こうしておくと前述の例では以下のようなファイルが生成される。
/home/mutoh/rails/cache/
`-- localhost.3000
|-- articles
| |-- list_en.cache
| |-- list_fr.cache
| |-- list_ja.cache
| `-- show
| `-- 24_ja.cache
`-- articles_ja.cache
