Video と Category の 2 つのモデルがあり、それらが互いに「has_and_belongs_to_many」の関係にある場合、いずれかが変更されたときにタッチを実行してキャッシュを無効にするにはどうすればよいですか?
1対多の関係のように、それらに「タッチ」することはできません。カテゴリ名を変更すると、そのカテゴリに属する動画は、キャッシュを無効にするまで変更を認識しません。マイ ビュー テンプレートには、各ビデオのカテゴリの名前が表示されます。
Video と Category の 2 つのモデルがあり、それらが互いに「has_and_belongs_to_many」の関係にある場合、いずれかが変更されたときにタッチを実行してキャッシュを無効にするにはどうすればよいですか?
1対多の関係のように、それらに「タッチ」することはできません。カテゴリ名を変更すると、そのカテゴリに属する動画は、キャッシュを無効にするまで変更を認識しません。マイ ビュー テンプレートには、各ビデオのカテゴリの名前が表示されます。
更新したいモデルでは、次のようなことができます:
class Video < ActiveRecord::Base
has_and_belongs_to_many :categories,
after_add: :touch_updated_at,
after_remove: :touch_updated_at
def touch_updated_at(category)
self.touch if persisted?
end
end
これで、ビデオにカテゴリが追加または削除されるたびに、ビデオの updated_at タイムスタンプが更新されます。ビデオが追加または削除されたときにカテゴリを更新する場合は、カテゴリ クラスで同じことを行うことができます。
タッチは 2 つの場合のみ使用できます。
記録上
category = Category.first
category.touch
belongs_to リレーションについて
belongs_to :category, :touch => true
したがって、HABTM リレーションで使用したい場合は、残念ながら手動で行う必要があります。それは次のようなものかもしれません:
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
ビデオがカテゴリにもアクセスできるようにする場合は、「循環」更新を回避する方法を見つける必要があることに注意してください。
それぞれ & find_each
update_attributes よりも each を優先する場合は、find_each を使用してレコードをバッチでロードします。これにより、すべてのレコードが同時にメモリに読み込まれることが回避され、アプリケーションがクラッシュする可能性があります。10,000 件のレコードがない場合、おそらく違いは見られませんが、テーブルが大きくなるにつれて、それぞれを使用すると速度が低下したり、壊れたりすることさえあります。
find_each(batch_size: 2000) { |video| video.touch }