0

投稿、コメント、およびコメントできるユーザーを含むブログがあるとします。ユーザーは、 http://localhost:3000/users/johnなどの SEO に適した URL を持っています(これは、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 %>

ここで、John がニックネームを Johnny に変更するとします。彼の URL はhttp://localhost:3000/users/johnnyに変更されます。投稿とコメントでフラグメント キャッシュを行うため、フラグメントの有効期限が切れていない限り、John のコメントは John の間違った URL を指します。この例では、John によるコメントを含むすべての投稿を手動でタッチまたは期限切れにすることができますが、複雑なアプリケーションでは非常に複雑なクエリが必要になり、エラーが発生しやすくなります。

ここでのベストプラクティスは何ですか? /users/john の代わりに /users/13 のような非 SEO フレンドリーな URL を使用する必要がありますか? それとも、キャッシュの有効期限が切れるまで、古い URL のリストを保持しますか? 私には良い解決策はありません。

編集: これは単純化された例に過ぎないことに注意してください。この場合、投稿を照会してそれらに触れるのは非常に簡単です。しかし、複雑なアプリはオブジェクト間に多くの関係があることを意味するため、ユーザーへの参照を持つすべてのオブジェクトを追跡することは困難です。これについて少し調べてみました -- Facebook ではユーザー名を 1 回しか設定できないため、この問題は存在しません。

4

2 に答える 2

2

キャッシュされた投稿を期限切れにするのは複雑ではないと思います。スイーパーを設定します。

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

def after_save(user)
  user.comments.collect(&:post).each do |post|
    expire_fragment post
  end
end
于 2011-01-17T09:00:07.463 に答える
0

たとえば、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

すべてのユーザーの投稿を更新するための1つのクエリ。それほど複雑ではありません。

于 2011-01-17T08:57:59.567 に答える