Неработающие ссылки при выполнении кэширования фрагментов в Rails - PullRequest
0 голосов
/ 17 января 2011

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

В модели используется сенсорный ввод для упрощения кэширования:

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 Джона, если срок действия фрагмента не истек.В этом примере может быть возможно вручную дотронуться до всех публикаций, содержащих комментарии Джона, или срок их действия истечет, но в сложном приложении это потребует очень сложных запросов и кажется очень подверженным ошибкам.

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

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

Ответы [ 2 ]

2 голосов
/ 17 января 2011

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

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

def after_save(user)
  user.comments.collect(&:post).each do |post|
    expire_fragment post
  end
end
0 голосов
/ 17 января 2011

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

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

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

...