そのため、何が機能し、何が機能しないかを確認するために、さまざまなアプローチを試しました。
繰り返しますが、状況を要約すると、私の目標は、オブジェクトが更新されたときにキャッシュされたページを期限切れにすることですが、コントローラーのアクションに依存せずにページを期限切れにすることです。従来のスイーパーは、コントローラー内のラインを使用して、機能する必要があることをスイーパーに通知します。この場合、モデル内で更新が行われているため、コントローラーでラインを使用することはできません。通常のスイーパー チュートリアルは、データベース オブジェクトとの主なやり取りがコントローラーを介して行われると想定しているため、機能しません。
これを読んで、私のコードを引き締める方法を見つけたら、コメントして教えてください。
まず、これで行き詰まって助けが必要な場合に備えて、実際に機能するものを見てみましょう。
私が試したすべてのことの中で、実際に機能しているように見えた唯一のことは、モデルのオブザーバーで after_update コマンドを宣言することでした。そのコマンドでは、expire_page アクションに明示的なコマンドを使用し、routes.rb で宣言されたパスを含めました。
そう。これは機能します:
config/routes.rb:
map.link 'l/:md5.:format', :controller => 'links', :action => 'show'
app/models/link_observer.rb:
def after_update(link)
ActionController::Base.expire_page(app.link_path(:md5 => link.md5))
end
「md5」は私のアプリに固有のものであることに注意してください。:id またはその他の一意の識別子を使用したい場合があります。
また、更新を行っているモデルのメソッドから ActionController::Base... 行を宣言すると、機能することもわかりました。つまり、Link.rb 内で、実際にデータベースを更新しているメソッドで、その行全体を差し込むだけで機能しました。しかし、将来、他の方法でそのページ キャッシュを期限切れにする可能性があるため、オブザーバーに抽出することをお勧めします。
さて、これについてグーグルで検索している場合に備えて、うまくいかなかったいくつかのことを見てみましょう。
link_observer.rb 内の after_update(link) メソッド内で「expire_page(...)」を呼び出すと、「undefined method `expire_page'」エラーが返されたため、機能しませんでした。
モデルを監視する Sweeper ファイルの作成が機能しませんでした。エラーコードは見つかりませんでしたが、やるべき仕事があることさえ認識していないようでした. これは、environment.rb 内で明示的に「config.load_paths += %W( #{RAILS_ROOT}/app/sweepers )」を呼び出した後でした。念のため、そのコードで何かを指で示しました。これは次のとおりです。
class LinkSweeper < ActionController::Caching::Sweeper
observe Link
def after_update(link)
clear_links_cache(link)
end
def clear_links_cache(link)
# DID NOT WORK expire_page :controller => 'links', :action => 'show', :md5 => link.md5
# DID NOT WORK expire_page '/l/'+ link.md5 + '.html'
# DID NOT WORK ActionController::Base.expire_page(app.link_path(:md5 => link.md5))
end
end
上記の例では、ディレクトリ /app/sweepers に link_sweeper.rb ファイルがありました。また、link_sweeper.rb を app/models ディレクトリに配置して、environment.rb の config.active_record.observers コマンドで呼び出してみました。
config.active_record.observers = :link_observer, :link_sweeper
しかし、それもうまくいきませんでした。
それで、ええ。これらの方法のいずれかが機能する可能性は十分にあり、コードで何かを台無しにしてしまった可能性もあります。しかし、私は本ですべてをやったと思います。
最終的に要約すると、Sweeper を使用してページ キャッシュを期限切れにするのではなく、モデルのオブザーバーで after_ コールバックを設定する必要があります。Base.expire_page メソッドへの明示的なパスを使用する必要があります。
def after_update(<model>) # where <model> is the name of the model you're observing
ActionController::Base.expire_page(app.<model>_path(:id => <model>.id)) # where <model> is the name of the model you're observing
end
うまくいけば、これは将来誰かを助けるでしょう。繰り返しますが、動作しないコードのどこかに別の方法をとるべきだった箇所があれば、お知らせください。私の作業コードにもっときついものがある場合は、それもお知らせください。