所以我尝试了许多不同的方法,看看哪些有效,哪些无效。
再次总结一下情况:我的目标是在对象更新时使缓存页面过期,但在不依赖控制器操作的情况下使它们过期。传统的清扫机使用控制器中的一条线来通知清扫机它需要运行。在这种情况下,我不能在控制器中使用一条线,因为更新是在模型中进行的。普通的清扫器教程不起作用,因为它们假定您与数据库对象的主要交互是通过控制器进行的。
如果在阅读本文时,您发现了一种收紧我的代码的方法,请发表评论并告诉我。
首先,让我们看看确实有效的东西,以防你也被困在这个问题上并需要帮助。
在我尝试过的所有事情中,唯一似乎真正起作用的是在模型的观察者中声明一个 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(...)”不起作用,因为它返回了“未定义的方法 `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
但这也不起作用。
是的。这些方法中的一种很可能会起作用,并且我在代码中搞砸了一些东西。但我认为我做的一切都是照本宣科的。
最后,总结一下:您希望在模型的 Observer 中设置一个 after_ 回调,而不是使用 Sweeper 来过期页面缓存。您需要使用 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
希望这会帮助其他人。同样,如果您在我的无效代码中看到我应该做一些不同的事情,请告诉我。如果您在我的工作代码中看到一些更严格的内容,也请告诉我。