1

Rails3アプリケーションでモデル化された次の関係があります。

class User < ActiveRecord::Base
  has_and_belongs_to_many :skills
end

class SkillsUser < ActiveRecord::Base
end

class Skill < ActiveRecord::Base
  has_and_belongs_to_many :users
end  

「SkillsUser」モデルは、ユーザーとスキルの間の多対多の関連付けを表します。このように、ユーザーが新しいスキルを追加し、そのスキルが「スキル」テーブル(つまり「Java」)にすでに存在すると言った場合、既存のスキルとユーザーの関係をskills_usersテーブルに作成するだけです。すべて良い。

ユーザービュー内に、スキルのリストを表示します。そして、私はそれらのスキルを包み込んだフラグメントキャッシングブロックを持っています。

<% cache([user,"skills"]) do %>
<div id="skills-grid">
      <% user.sorted_skills.each do |s| %>
        ...
  <% end %>
</div>
<% end %>

別の編集ページで、ユーザーはスキルを追加または削除できます。このアクションは、skills_usersレコードを作成または削除するだけです。そして、これが発生した場合、スキルがユーザービューに適切に表示されるように、フラグメントキャッシュを無効にする必要があります。

そこで、skills_usersの関係を観察することが人生の目的であるCacheSweeperを作成しました。コントローラは次のとおりです。

class SkillsController < ApplicationController
  autocomplete :skill, :name
  cache_sweeper :skill_user_sweeper

  def create
    @user  = User.find(params[:user_id])
    #Make sure the current user has access to 
    #associate a skill to the user in the request
    if(@user.id = current_user.id)
      SkillsHelper.associate_skill(@user,params[:skill][:name])
      @skill  = Skill.find_by_name(params[:skill][:name])
    end
    respond_to do |format|
      format.js
    end
  end

  def destroy
    @skill = Skill.find_by_id(params[:id])
    @user  = User.find_by_id(params[:user_id])
    #Destroy the relationship, not the skill
    @user.skills.delete(@skill) if(@skill.can_be_tweaked_by?(current_user))

    respond_to do |format|
      format.js
    end
   end
end

そして、これがスイーパーです:

class SkillUserSweeper < ActionController::Caching::Sweeper
  observe SkillsUser

  def after_create(skill_user)
    expire_cache_for(skill_user)
  end

  def after_update(skill_user)
    expire_cache_for(skill_user)
  end

  def after_destroy(skill_user)
    expire_cache_for(skill_user)
  end

  private
  def expire_cache_for(skill_user)
    expire_fragment([skill_user.user,"skills"])
  end  
end

問題は、skills_usersレコードを追加または削除した後(SkillsControllerで「作成」または「破棄」した後)、スイーパーが呼び出されないことです。私のプロジェクトでは他のスイーパーが働いていますが、それらのどれも多対多の関連を観察していません。

それでは、私の質問は、「has_and_belongs_to_many」の関連付けを監視するためにCacheSweeperをどのように作成するかということです。

4

1 に答える 1

3

キーとしてuserではなくuser.idを使用してみます。すなわち変更

<% cache([user,"skills"]) do %>

<% cache([user.id,"skills"]) do %>

また、コールバック内にロガーメッセージを追加し、SkillUserSweeperクラスにロガーメッセージを追加して、ロードされていることを確認します。

于 2011-09-28T04:07:00.587 に答える