在Rails中,Sweeper不会在模型中调用

我正在使用Rails应用程序,我正在使用页面缓存来存储静态html输出。 缓存工作正常。 不过,我在刷新缓存时遇到了问题。

我相信我的问题部分是因为我没有从我的控制器中过期缓存。 所有必要的操作都在模型中处理。 这看起来应该是可行的,但是我发现所有对基于模型的缓存过期的引用似乎已过时,或者不起作用。

在我的environment.rb文件中,我在打电话

config.load_paths += %W( #{RAILS_ROOT}/app/sweepers )

我在/ sweepers文件夹中有一个LinkSweeper文件:

class LinkSweeper < ActionController::Caching::Sweeper
  observe Link

  def after_update(link)
    clear_links_cache(link)
  end

  def clear_links_cache(link)
  # expire_page :controller => 'links', :action => 'show', :md5 => link.md5
    expire_page '/l/'+ link.md5 + '.html'
  end
end

那么...为什么当我更新模型时,它不会删除缓存页面? (过程:使用脚本/控制台,我从数据库中选择项目并保存它们,但它们的相应页面并未从缓存中删除),并且我还调用Link模型中通常会调用的特定方法清扫车。 两者都不起作用。

如果重要,则缓存文件是链接表中键值的md5散列值。 缓存页面被存储为/l/45ed4aade64d427...99919cba2bd90f.html。

从本质上讲,似乎Sweeper并没有实际观察链接。 我还读到(在这里),可能只是将清理程序添加到environment.rb中的config.active_record.observers,但似乎没有这样做(我不确定app / sweepers的load_path在environment.rb中取消了)。


请注意:您可以在ApplicationController中使用cache_sweeper

class ApplicationController < ActionController::Base
  cache_sweeper :my_sweeper
end

class MySweeper < ActionController::Caching::Sweeper
  observe MyModel

  def after_update(my_model)
    expire_page(...)
  end
end

所以我尝试了很多不同的方法,看看有什么效果,哪些没有。

再次总结一下情况: 我的目标是在对象更新时使缓存页失效,但不依赖Controller操作而使其失效。 传统的扫地机在控制器中使用一条线来通知清扫机它需要起作用。 在这种情况下,我不能在控制器中使用一条线,因为更新在模型中发生。 正常的清理程序教程不起作用,因为他们认为您与数据库对象的主要交互是通过控制器进行的。

如果在阅读本文时,您会看到加强我的代码的方法,请发表评论并告诉我。

首先,让我们看看可以发挥作用的事情,以防万一你也停滞不前,并且需要帮助。

在我尝试的所有事情中,似乎真正起作用的唯一事情是在模型的Observer中声明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中,在实际更新数据库的方法中,如果我只是将整条线插入,它就可以工作。 但是由于我可能想在将来的其他方法上将页面缓存过期,所以我宁愿将它提取到Observer中。

现在,让我们看看一些DID不起作用的东西,以防你为此搜索。

在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

但是这也行不通。

嗯是的。 这些方法中的一种很可能会起作用,并且我在代码中搞砸了一些东西。 但是我认为我完成了本书的一切。

总而言之,总结一下:您不想使用Sweeper过期页面缓存,而是希望在模型的Observer中设置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

希望这会帮助其他人。 再说一遍,如果你在我的不工作的代码中看到任何地方,我应该做些不同的事情,请告诉我。 如果您在我的工作代码中看到可能更加紧密的内容,请让我知道。


尝试进行片段缓存时,我遇到了同样的问题(导轨3)。 无法让清扫人员观察,所以我决定让解决方案成为AR Observer,并调用ApplicationController.new.expire_fragment(...)

链接地址: http://www.djcxy.com/p/60355.html

上一篇: In Rails, a Sweeper isn't getting called in a Model

下一篇: conv from Apple Accelerate Framework