Rails3 Cache Sweeper для ассоциации has_and_belongs_to_many - PullRequest
1 голос
/ 11 августа 2011

У меня есть следующие отношения, смоделированные в приложении 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»), я просто создаю связь между существующим навыком и пользователем в таблице skill_users.Все хорошо.

В поле зрения пользователя я отображаю список навыков.И у меня есть блок кэширования фрагментов, обернутый вокруг этих навыков.

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

На отдельной странице редактирования Пользователь может добавить или удалить Навык.Это действие просто создает или удаляет запись skill_users.И когда это происходит, мне нужно аннулировать кэш фрагментов, чтобы навыки соответствующим образом отображались в представлении пользователя.

Итак, я создал CacheSweeper, цель которого в жизни состоит в том, чтобы наблюдать за отношением skill_users.Вот контроллер:

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

Проблема в том, что после добавления или удаления записи skill_users (после «создания» или «уничтожения» на SkillsController), уборочная машина никогда не вызывается.У меня есть другие подметальные машины, работающие в моем проекте, но ни один из них не наблюдает ассоциации многие-ко-многим.

Тогда мой вопрос: как создать CacheSweeper для наблюдения ассоциации has_and_belongs_to_many?

1 Ответ

2 голосов
/ 28 сентября 2011

Я не могу оставлять комментарии - извините

Я бы попытался использовать user.id, а не user в качестве ключа. то есть изменить

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

до

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

Я бы также добавил сообщения журнала в колбэки, а также сообщение журнала в классе SkillUserSweeper, чтобы убедиться, что оно загружается.

...