2011-08-11 2 views
1

위해 나는 Rails3 응용 프로그램에서 모델로 다음과 같은 관계를 한 : 는 Rails3 캐시 스위퍼 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 

은 "SkillsUser"모델

사용자와 기술 사이의 many-to-many 연관을 나타냅니다. 이 방법으로 사용자가 새 스킬을 추가하고 스킬이 이미 "스킬"테이블 (예 : "Java")에있는 경우 skill_users 테이블에서 기존 스킬과 사용자 간의 관계를 간단히 작성합니다. 문제 없다.

사용자보기 내에서 스킬 목록을 표시합니다. 그리고 그 기술을 감싸는 조각 캐싱 블록이 있습니다.

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

별도의 편집 페이지에서 사용자가 스킬을 추가하거나 삭제할 수 있습니다. 이 작업은 단순히 skills_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 

문제입니다 ("생성"또는 SkillsController의 "파괴"후)을 skills_users 기록을 추가하거나 제거한 후, 스위퍼 절대로 호출되지 않습니다. 나는 다른 청소부들이 내 프로젝트에서 일하고 있지만 그들 중 누구도 다 대 다 연합을 관찰하지 않습니다.

내 질문에, 그렇다면 "has_and_belongs_to_many"연관을 관찰하기 위해 CacheSweeper를 만드는 방법은 무엇입니까?

나는 키와 user.id이 아닌 사용자를 사용하려고 할 것 죄송합니다 -

답변

2

내가 덧글을 남길 수 없습니다. 나는 또한이로드되고 있는지 확인하기 위해 SkillUserSweeper 클래스의 콜백뿐만 아니라 로거 메시지 내부 로거 메시지를 추가

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

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

에 즉 변경합니다.

+0

감사합니다. 나는 그것들을 시험해 보았고 SkillsUserSweeper는 적재되지 않았다. 이것은 컨트롤러에서 SkillsUserSweeper 객체와 명시 적으로 상호 작용하지 않기 때문에 가능성이 있습니다. 레일스는 스위퍼 동작을 트리거하지 않습니다. –