Rails3 Cache Sweeper для ассоциации has_and_belongs_to_many
У меня есть следующие отношения, смоделированные в приложении 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 ответ
Я не могу оставлять комментарии - извините
Я бы попытался использовать user.id, а не user в качестве ключа. т.е. изменить
<% cache([user,"skills"]) do %>
в
<% cache([user.id,"skills"]) do %>
Я бы также добавил сообщения журнала в колбэки, а также сообщение журнала в классе SkillUserSweeper, чтобы убедиться, что оно загружается.