2011-01-17 6 views
0

Angenommen, es gibt einen Blog mit Posts, Kommentaren und Benutzern, die Kommentare schreiben können. Benutzer haben SEO-freundliche URLs wie http://localhost:3000/users/john (dies kann leicht mit permalink_fu getan werden).Fehler beim Zwischenspeichern von Fragmenten in Rails

Das Modell verwendet Touch-Caching zu vereinfachen:

class Post 
    has_many :comments 
end 

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

Und die Ansicht Code so etwas wie dieses wäre:

<%= 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 %> 

Jetzt John ändert seinen nick zu Johnny annehmen - seine URL Änderungen http://localhost:3000/users/johnny. Aufgrund des Zwischenspeicherns von Fragmenten bei Posts und Kommentaren verweisen die Kommentare von John auf die falsche URL von John, es sei denn, das Fragment ist abgelaufen. Es ist möglich, alle Posts, die Kommentare von John in diesem Beispiel enthalten, manuell zu berühren oder abzulaufen, aber in einer komplexen Anwendung würde dies sehr komplexe Abfragen erfordern und sehr fehleranfällig erscheinen.

Was ist die beste Vorgehensweise hier? Sollte ich nicht SEO-freundliche URLs wie/users/13 anstelle von/users/john verwenden? Oder vielleicht eine Liste der alten URLs behalten, bis der Cache abgelaufen ist? Keine Lösung sieht gut aus.

EDIT: Bitte beachten Sie, dies ist nur ein vereinfachtes Beispiel - es ist auf jeden Fall sehr einfach, Posts abzufragen und sie in diesem Fall zu berühren. Eine komplexe App impliziert jedoch viele Beziehungen zwischen Objekten, wodurch es schwierig wird, jedes Objekt zu verfolgen, das einen Verweis auf einen Benutzer hat. Ich habe ein wenig darüber recherchiert - Facebook kann nur einmal Ihren Benutzernamen festlegen, so dass dieses Problem nicht existiert.

Antwort

2

Ich sehe nicht, es wäre komplex, zwischengespeicherte Beiträge zu verfallen. Einrichten einer Kehrmaschine:

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

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

Passt das Beispiel, wäre aber in einer größeren App schwer. Ich habe die Frage aktualisiert, um zu verdeutlichen, dass ich nicht nach einer Lösung für das vereinfachte Beispiel suche. – Jose

+0

Ich sehe wirklich kein Problem, solange Ihre Beziehungen zwischen Ihren Modellen definiert sind, können Sie sie dem Kehrer hinzufügen. Übrigens möchtest du vielleicht google_friendly_id googeln. In Ihrem Benutzerszenario würde es nachverfolgen und auf die neue URL umleiten, bis Ihr Cache abläuft. – mark

+0

So friendly_id hält eine Geschichte von Schnecken. Ich wusste nichts davon, aber das war die Art von Lösung, nach der ich suchte, also vielen Dank, Mark! – Jose

0

würde ich einen BEFORE_SAVE Filter zum Beispiel

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 

Eine Abfrage jeden Benutzers Beitrag zu aktualisieren. Nicht wirklich komplex.

Verwandte Themen