Разбитые ссылки при выполнении кэширования фрагментов в рельсах

StackOverflow https://stackoverflow.com/questions/4711241

Вопрос

Предположим, есть блог с сообщениями, комментариями и пользователями, которые могут комментировать. У пользователей есть SEO-удобные URL-адреса, такие как http: // localhost: 3000/пользователи/Джон (Это можно легко сделать с помощью permalink_fu).

Модель использует Touch, чтобы упростить кэширование:

class Post
  has_many :comments
end

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

И код представления будет чем -то вроде этого:

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

Теперь предположим, что Джон меняет Ник на Джонни - его URL меняется на http: // localhost: 3000/users/johnny. Анкет Из -за того, что вы делаете кэширование фрагментов по сообщениям и комментариям, комментарии Джона будут указывать на неправильный URL Джона, если фрагмент не истек. В этом примере можно вручную прикоснуться или истечь ко всем сообщениям, которые содержат комментарии Джона, но в сложном приложении это потребует очень сложных запросов и кажется очень подверженным ошибкам.

Какая здесь лучшая практика? Должен ли я использовать URL-адреса, такие как URL-адреса, такие как /пользователи /13 вместо /пользователя /Джон? Или, может быть, соблюдать список старых URL -адресов, пока кэш не истек? Ни одно решение для меня не выглядит хорошо.

РЕДАКТИРОВАТЬ: Обратите внимание, что это всего лишь упрощенный пример - определенно очень просто запрашивать сообщения и прикоснуться к ним в этом случае. Но сложное приложение подразумевает много отношений между объектами, что затрудняет отслеживание каждого объекта, который имеет ссылку на пользователя. Я немного исследовал это - Facebook позволяет только один раз установить свое имя пользователя, поэтому этой проблемы не существует.

Это было полезно?

Решение

Я не вижу, чтобы это было бы сложно истекать кэшированным сообщениями. Установите подметалку:

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

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

Другие советы

Я бы использовал, например, фильтр до_Саве

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

Один запрос обновить пост каждого пользователя. Не очень сложно.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top