如何联系HABTM关系 [英] How to touch a HABTM relation
问题描述
如果您有2个模型(视频和类别),并且它们彼此之间具有 has_and_belongs_to_many关系,那么当其中一个模型发生更改时,如何执行触摸操作以使缓存无效?
If you have 2 models, Video and Category and they have a "has_and_belongs_to_many" relation with each other, how do you perform a touch to invalidate the cache when one of them changes?
您不能像一对多关系那样对它们进行触摸。现在,当我更改类别名称时,在我使缓存无效之前,属于该类别的视频才知道更改。我的视图模板显示每个视频的类别名称。
You can't put "touch" on them like you can with a one-to-many relation. Now when i change a category name, the videos that belong to that category don't know about the change until i invalidate the cache. My View Templates show the name of the Category for each Video.
推荐答案
触摸只能在两种情况下使用。
Touch can be used only in two case.
记录上
category = Category.first
category.touch
在归属关系上
belongs_to :category, :touch => true
因此,如果您想在HABTM关系中使用它,恐怕您会必须手动执行。可能是这样的:
So if you want to use it on a HABTM relation, I'm afraid that you'll have to do it manually. It could be something like:
class Category
before_save :touch_videos
def touch_videos
videos.touch
end
end
class Video
def self.touch
update_attributes(:updated_at => Time.now)
# or
each { |video| video.touch } # Make a proper touch
end
end
请注意如果您还希望允许视频也可以触摸类别,则必须找到一种避免循环更新的方法。
Be aware that if you want to allow Video to touch categories as well, you'll have to find a way to avoid "circular" updates.
每个& find_each
如果相对于update_attributes,您更喜欢每一个,请使用find_each批量加载记录。这样可以避免将所有记录同时加载到内存中,并有可能使应用程序崩溃。如果您没有1万条记录,则可能看不到任何区别,但是随着表的增长,如果您使用每条记录,它将变得更慢甚至中断。
If you prefer each over update_attributes, use find_each to load records by batch. This will avoid loading all records at the same time in memory and potentially crash the application. If you don't have 10k records, you probably won't see any difference, but as your table grows, it will get slower or even break if you use each.
find_each(batch_size: 2000) { |video| video.touch }
这篇关于如何联系HABTM关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!