23

Video と Category の 2 つのモデルがあり、それらが互いに「has_and_belongs_to_many」の関係にある場合、いずれかが変更されたときにタッチを実行してキャッシュを無効にするにはどうすればよいですか?

1対多の関係のように、それらに「タッチ」することはできません。カテゴリ名を変更すると、そのカテゴリに属する​​動画は、キャッシュを無効にするまで変更を認識しません。マイ ビュー テンプレートには、各ビデオのカテゴリの名前が表示されます。

4

2 に答える 2

44

更新したいモデルでは、次のようなことができます:

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 タイムスタンプが更新されます。ビデオが追加または削除されたときにカテゴリを更新する場合は、カテゴリ クラスで同じことを行うことができます。

于 2014-05-28T23:10:47.150 に答える
13

タッチは 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 }
于 2013-05-31T11:45:02.720 に答える