Rails 缓存清理器和模型回调触发
我有以下课程:
class Vigil < ActiveRecord::Base
after_update :do_something_cool
private
def do_something_cool
# Sweet code here
end
end
class NewsFeedObserver < ActionController::Caching::Sweeper
observe Vigil
def after_update
# Create a news feed entry
end
end
一切都按预期进行;但是,sweeper 中的 after_update 要求模型中的 do_something_cool 方法完成后才能正常运行。问题在于清理器中的 after_update 在 do_something_cool
回调之前(或者可能同时)被调用,并且它导致了问题。
有谁知道如何强制清除器中的 after_update
在模型回调后触发?有更好的方法来实现这一目标吗?
更新/修复:事实证明,与下面的答案不同,观察者回调实际上是以正确的顺序触发的(在模型回调之后)。当我发现这一点时,我意识到一定还有其他问题。
do_something_cool
方法会销毁所有守夜者的插槽,并用正确时间的正确数量的插槽替换它们。观察者依靠时段的数量来确定守夜应该持续多长时间。因此,根本问题是所有守夜者的插槽都被销毁,并且数据被缓存,因此当我从观察者调用 vigil.slots
时,它正在使用缓存(已销毁的插槽)数据。解决方案:只需在 do_something_cool
末尾调用 vigil.slots(true) 即可重新加载/重新缓存新创建的插槽!
I have the following classes:
class Vigil < ActiveRecord::Base
after_update :do_something_cool
private
def do_something_cool
# Sweet code here
end
end
class NewsFeedObserver < ActionController::Caching::Sweeper
observe Vigil
def after_update
# Create a news feed entry
end
end
Everything works as expected; however, the after_update
in the sweeper requires that the do_something_cool
method in the model has finished before it can run properly. The problem is that the after_update
in the sweeper is being called before (or perhaps at the same time as) the do_something_cool
callback and it's causing problems.
Does anyone know how to force the after_update
in the sweeper to fire after the model callback? Is there better way to achieve this?
Update/Fix: As it turns out, unlike the answer below states, the observer callbacks actually ARE firing in the correct order (after the model callbacks). When I discovered this, I realized something else must be wrong.
The do_something_cool
method destroys all of a vigil's slots, and replaces them with the correct number of slots with the correct times. The observer relies on the number of slots to figure out how long the vigil should last. So, the underlying problem was that all of the vigil's slots were being destroyed, and that data was cached, so when I called vigil.slots
from the observer, it was using the cached (destroyed slots) data. The solution: simply call vigil.slots(true) at the end of do_something_cool
to reload/recache the newly created slots!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
它不会同时运行,但你是对的,看起来 Sweeper 回调是在 Model 回调之前运行的。
这篇文章可能会有所帮助:http://upstre.am/ 2007/10/27/using-and-testing-activerecordrails-observers/
大约一半的时间(搜索“callback :after_read”)他们尝试为其观察者创建自定义回调。您可以使用它来创建一个 after_something_cool ARObserver 方法,当模型完成很酷时会调用该方法,例如
免责声明:我从来没有这样做过,而且我总是发现扫地机在 Rails 版本之间不稳定,所以对它们有效的方法可能不起作用为你 :(
It's not going to be running at the same time but you're right, it looks like the Sweeper callback is being run before the Model one.
This post might be helpful : http://upstre.am/2007/10/27/using-and-testing-activerecordrails-observers/
About halfway down (search for 'callback :after_read') they have tried to create custom callbacks for their observers. You could use this to create a after_something_cool ARObserver method that gets called when the Model is done being cool e.g.
Disclaimer: I've never done this and I've always found sweepers to be temperamental between rails versions so what worked for them might not work for you :(