«前の日記(2007-12-15) 最新 次の日記(2007-12-24)» 編集

野ログはノロキュアMaxHeart


2007-12-17

_ map.resourcesとApacheでページキャッシュが共存できない件とその解決法

RailsはRestfulな方向に進化していて、最近は

map.resourcesというメソッドを使いリソースに対するルーティングを一気に定義したりできます。

map.resources :targets

とroutesに書いたとき、定義されるルーティングは

              targets GET    /targets                         {:action=>"index", :controller=>"targets"}
    formatted_targets GET    /targets.:format                 {:action=>"index", :controller=>"targets"}
                      POST   /targets                         {:action=>"create", :controller=>"targets"}
                      POST   /targets.:format                 {:action=>"create", :controller=>"targets"}
           new_target GET    /targets/new                     {:action=>"new", :controller=>"targets"}
 formatted_new_target GET    /targets/new.:format             {:action=>"new", :controller=>"targets"}
          edit_target GET    /targets/:id/edit                {:action=>"edit", :controller=>"targets"}
formatted_edit_target GET    /targets/:id/edit.:format        {:action=>"edit", :controller=>"targets"}
               target GET    /targets/:id                     {:action=>"show", :controller=>"targets"}
     formatted_target GET    /targets/:id.:format             {:action=>"show", :controller=>"targets"}
                      PUT    /targets/:id                     {:action=>"update", :controller=>"targets"}
                      PUT    /targets/:id.:format             {:action=>"update", :controller=>"targets"}
                      DELETE /targets/:id                     {:action=>"destroy", :controller=>"targets"}
                      DELETE /targets/:id.:format             {:action=>"destroy", :controller=>"targets"}

となります。

現在PUTやDELETEを実装しているブラウザはほぼないので,実際は_methodというパラメータにメソッド名を入れて渡している感じになります。

これにより,

/targets/:id

に対してGETでアクセスした場合はshow,PUTでアクセスした場合はupdate,DELETEでアクセスした場合はdestroyというようになることを擬似的に実現しています。

この時に問題になるのがページキャッシュ。

ページキャッシュは一度目にアクセスを行われた時に、指定されたパスにファイルがある場合そのファイルを返す。ということによって高速なアクセスを実現させています。

Apacheの場合標準では.htaccessに対して

RewriteRule ^$ index.html [QSA]
RewriteRule ^([^.]+)$ $1.html [QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ dispatch.cgi [QSA,L]

というような記述があります。

一度/targets/1にアクセスがあった場合/targets/1.htmlを生成し、二度目からはRailsにアクセスを通すことなく、Apacheが/targets/1.htmlを返却します。

しかし、map.resourcesを利用した場合、見る場合、更新する場合、削除する場合全て同じ/targets/1にアクセスします。

現状のページキャッシュでは消したいとき、更新したいときもページキャッシュが存在する場合は、そのファイルを返してしまい、意図した通りにできないのではないか…

と考えました。

apacheとmongrelでそれぞれチェックしてみたところ、

mongrelでは意図した通りの動くものの、apacheではやはり.htaccessの指定通りキャッシュを返します

(当たり前ですが…)

現状mongrelをAPとして使っている構成が多いとは思いますが、たいていの場合、フロントにApacheを置いてmod_proxy_balancerでアクセスをmongrelに振り分けていると思います。

その場合フロントのApacheに静的ファイルを返させるような設定にしている場合がほとんどかと思われます。

そのような場合destroyやupdateに対してもページキャッシュを返してしまい、意図した通り動いてくれません。

なので.htaccessを変更して意図した通りに動くように変更しましょう。

RewriteRule ^$ index.html [QSA]
RewriteRule ^([^.]+)$ $1.html [QSA]
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_METHOD} !GET
RewriteRule ^(.*)$ dispatch.cgi [QSA,L]

私は上記のように変更を行いました。

GET以外のメソッドでアクセスされた時は、ページキャッシュを利用しないよう設定しました。

これで意図したように動作するはずです。

.htaccessの中身はもう少しいろいろ考えたい…

僕は普段はこれプラスページキャッシュは/cache/以下に全て保存するようにしてます。

そうすると

rm -rf ./public/cache/

とかでキャッシュ全部消せて楽。

svnから除外する設定も楽だし。

補足

onkブログに書いてある件だと多分無理です。

ページキャッシュはクエリーストリングを消したhtmlファイルを基本生成します。

あとうまく生かせる方法あったとしても上手いこと使えるヘルパー作らないと面倒な予感。

(もし勘違いした話してたらごめんなさい)

editが動かない。

ちょっと理由まで調査してないのですが、

上記の設定をしてもページキャッシュが存在するときeditが動きません。

(上記のをしなくても動きません。)

/targets/1/edit

/targets/1.html/edit

にリライトされてしまい、問題が発生します。

僕の設定ではうまくいってるので、原因解決には一切なってないですけど、僕の設定を紹介しておきます。

environment.rbで

config.action_controller.page_cache_directory = RAILS_ROOT+"/public/cache/"

と書いておく。

.htaccessは

RewriteRule ^$ cache/index.html [QSA]
RewriteRule ^([^.]+)$ cache/$1.html [QSA]
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_METHOD} !GET
RewriteRule ^(.*)$ dispatch.cgi [QSA,L]

こんな感じで。

解決したみたいです

原因はMultiViewみたいですねー。

考えてみるとたしかに!

MultiViewを切るのもいいですが、ページキャッシュを保存するディレクトリを別の場所にしてしまう方をおススメします。

なんでこんなくだらないことに必死かって?

CGIしか使えないレンタルサーバでRails使うにはページキャッシュが必須だからです!!←結論

Tags: dev rails
お名前:
E-mail:
右の画像に書かれている文字列を入力してください:
コメント:
[]

«前の日記(2007-12-15) 最新 次の日記(2007-12-24)» 編集

最近の記事

最近のコメント

  1. nog (04-07)
  2. 梅の里 (04-02)
  3. 匿名 (03-30)
  4. nog (03-10)
  5. 榊祐介 (03-09)
  6. wataru (12-24)
  7. 元木仁 (12-06)
  8. 榊 (09-09)
  9. 榊 (09-09)
  10. nog (09-09)

最近のトラックバック

  1. treasuring misc.:軍議nightにて、.. (2007-08-21 13:01)
  2. プッチャンの無双声優マニアック.. (2007-06-06 11:01)
  3. エム会議:まるでドラゴンクエス.. (2006-12-19 00:05)

作ったもんとか

チョコ鑑定
あなたのもらったチョコのレシピを鑑定します。
今時名前メーカー
あなたに今風の名前をプレゼントします。
コピペ運動会
ユーザー参加型コピペ投稿サイト
はうまっち?
楽天市場の価格を当て合うコミュニティ
Award on Rails楽天賞受賞
公開メモ
公開してるメモ用wiki

アンテナ

タグリスト

過去ログ

2003|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|
2006|05|06|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|04|05|06|07|09|11|
2009|01|02|03|04|05|06|

その他

フィードメーター - 野ログはノロキュアMaxHeart あわせて読みたいブログパーツ