J'ai les relations suivantes modelées dans une application Rails3:Rails3 Cache Sweeper pour l'association has_and_belongs_to_many
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
Le modèle « SkillsUser » représente le nombre à plusieurs entre les utilisateurs et les compétences. De cette manière, lorsqu'un utilisateur ajoute une nouvelle compétence et que cette compétence existe déjà dans le tableau "compétences" (par exemple "Java"), je crée simplement la relation entre la compétence existante et l'utilisateur dans la table skills_users. Tout bon.
Dans la vue de l'utilisateur, j'affiche une liste de compétences. Et j'ai un bloc de mise en cache fragmenté autour de ces compétences.
<% cache([user,"skills"]) do %>
<div id="skills-grid">
<% user.sorted_skills.each do |s| %>
...
<% end %>
</div>
<% end %>
Sur une page d'édition distincte, un utilisateur peut ajouter ou supprimer une compétence. Cette action crée ou supprime simplement un enregistrement skills_users. Et lorsque cela se produit, je dois invalider le cache de fragments afin que les compétences soient correctement affichées dans la vue utilisateur. J'ai donc créé un CacheSweeper dont le but dans la vie est d'observer la relation skills_users. Voici le contrôleur:
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
Et voici la balayeuse:
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
Le problème est, après l'ajout ou la suppression d'un skills_users enregistrement (après « créer » ou « détruire » sur le SkillsController), la balayeuse n'est jamais invoqué. J'ai d'autres balayeurs travaillant dans mon projet, mais aucun d'entre eux n'observe des associations plusieurs-à-plusieurs.
Ma question est donc comment créer un CacheSweeper pour observer une association "has_and_belongs_to_many"?
Merci. J'ai essayé ceux-ci, et le SkillsUserSweeper n'est pas chargé. Cela est probablement dû au fait que je n'interagis pas explicitement avec un objet SkillsUserSweeper dans mon contrôleur et qu'en tant que tel, Rails ne déclenche pas d'actions de balayage. –