2011-01-17 3 views
0

게시물, 댓글 및 댓글을 달 수있는 사용자가있는 블로그가 있다고 가정합니다. 사용자는 http://localhost:3000/users/john과 같은 SEO 용 URL을 사용합니다 (permalink_fu를 사용하면 쉽게 수행 할 수 있습니다). 자신의 URL 변화에 -레일에서 조각 캐싱을 할 때 깨진 링크

<%= cache @post do %> 

    <h1><%= @post.title %></h1> 
    <%= @post.content %> 

    <%= @post.comments.each do |comment| %> 
    <%= link_to h(comment.user), comment.user %> said: 
    <%= comment.content %> 
    <% end %> 

<% end %> 

지금 존을 가정 조니 그의 별명을 변경 :이 같은 것

class Post 
    has_many :comments 
end 

class Comment 
    belongs_to :post, :touch=>true 
end 

그리고 뷰 코드 :

모델은 캐싱을 단순화하기 위해 터치를 사용하여 http://localhost:3000/users/johnny. 게시물과 주석에 조각 캐싱을 수행하기 때문에 John의 설명은 조각이 만료되지 않는 한 John의 잘못된 URL을 가리 킵니다. 이 예제에서 John이 주석을 포함하는 모든 게시물을 수동으로 만지거나 만료시킬 수도 있지만 복잡한 응용 프로그램에서는 매우 복잡한 쿼리가 필요하며 오류가 발생하기 쉽습니다.

여기에서 가장 좋은 방법은 무엇입니까?/users/john 대신/users/13과 같은 비 -SEO 친화적 인 URL을 사용해야합니까? 또는 캐시가 만료 될 때까지 이전 URL 목록을 유지 하시겠습니까? 어떤 해결책도 나에게 좋지 않습니다.

편집 : 이것은 단순한 예에 불과합니다. 게시물을 쿼리하고이 경우 터치하는 것이 매우 간단합니다. 그러나 복잡한 응용 프로그램은 객체 간의 많은 관계를 의미하므로 사용자에 대한 참조가있는 모든 객체를 추적하기 어렵습니다. 나는 이것에 대해 조금 연구했다 - 페이스 북은 사용자 이름을 한 번만 설정할 수 있기 때문에이 문제는 존재하지 않는다.

답변

2

캐시 된 게시물이 만료되는 것이 복잡해 보이지 않습니다. 스위퍼 설정 :

class UserSweeper < ActionController::Caching::Sweeper 
observe User 

def after_save(user) 
    user.comments.collect(&:post).each do |post| 
    expire_fragment post 
    end 
end 
+0

위의 예는 적합하지만 더 큰 응용 프로그램에서는 어려울 것입니다. 단순화 된 예제에 대한 해결책을 찾고 있지 않다는 것을 명확히하기 위해 질문을 업데이트했습니다. – Jose

+0

모델 사이에 관계가 정의되어 있으면 스위퍼에 추가 할 수있는 한 어떤 문제도 실제로 나타나지 않습니다. 덧붙여서, 당신은 Google friendly_id를 원할 수 있습니다. 캐시가 만료 될 때까지 사용자 시나리오에서 추적을 유지하고 새 URL로 리디렉션됩니다. – mark

+0

그래서 friendly_id는 슬러그의 기록을 유지합니다. 나는 그것에 대해 몰랐다. 그러나 이것은 내가 찾고 있었던 해결책이었다. 그래서 고마워, Mark! – Jose

0

나는 모든 사용자의 게시물을 업데이트 할 예를 들어

class User 
    has_many :posts 

    before_save :touch_posts 

    private 
    def touch_posts 
    Post.update_all({:updated_at => Time.now}, {:user_id => self.id}) if self.login_changed? 
    true 
    end 
end 

한 쿼리를 before_save 필터를 사용하십시오. 별로 복잡하지 않습니다.

관련 문제