質問

コメントできる投稿、コメント、ユーザーのブログがあるとします。ユーザーは、などの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を指します。この例では、ジョンによるコメントを含むすべての投稿を手動で触れたり期限切れにしたりすることが可能ですが、複雑なアプリケーションでは非常に複雑なクエリが必要であり、非常にエラーが発生しやすいようです。

ここでのベストプラクティスは何ですか? /users /johnの代わりに /users /13などの非セオフレンドリーなURLを使用する必要がありますか?または、キャッシュが期限切れになるまで古い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

他のヒント

たとえば、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つのクエリ。本当に複雑ではありません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top