Domanda

Supponiamo che ci sia un blog con post, commenti e gli utenti che possono commentare. Gli utenti hanno URL SEO-friendly, come http: // localhost: 3000 / utenti / John (questo può essere fatto facilmente utilizzando permalink_fu).

Gli usi modello toccare per la memorizzazione nella cache Semplificare:

class Post
  has_many :comments
end

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

E il codice vista sarebbe qualcosa di simile:

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

Ora supponiamo John cambia il suo nick a Johnny - le sue modifiche URL a http: // localhost: 3000 / utenti / johnny. A causa di fare caching dei frammenti in post e commenti, i commenti di John punterà all'URL sbagliato Giovanni a meno che il frammento è scaduto. Può essere possibile toccare manualmente o alterarsi tutti i messaggi che contengono i commenti di John in questo esempio, ma in un'applicazione complessa ciò richiederebbe query molto complesse e sembra molto soggetto ad errori.

Qual è la migliore pratica qui? Dovrei usare URL non SEO-friendly come ad esempio / utenti / 13 invece di / utenti / John? O forse tenere un elenco di URL vecchio fino a scadenza della cache? Nessuna soluzione sembra buono per me.

EDIT: Si prega di notare che questo è solo un esempio semplificato - è sicuramente molto semplice da messaggi di interrogazione e di toccare in questo caso. Ma un'applicazione complessa implica molte relazioni tra gli oggetti che lo rende difficile da rintracciare ogni oggetto che ha un riferimento a un utente. Ho ricercato un po 'su questo -. Facebook consente solo di impostare il nome utente una volta, quindi questo problema non esiste

È stato utile?

Soluzione

non vedo che sarebbe stato complesso per scadere i messaggi memorizzati nella cache. Impostare una spazzatrice:

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

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

Altri suggerimenti

userei un filtro before_save ad esempio

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

Una richiesta per aggiornare il post di ogni utente. Non proprio complesso.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top