在哪里修补 Rails ActiveRecord::find() 以首先检查内存中的集合?

发布于 2024-08-07 02:38:59 字数 1070 浏览 1 评论 0原文

由于一些复杂的原因,我想创建一些像这样工作的东西:

# Controller:
@comments = @page.comments # comments are threaded
# child comments still belong to @page
...  
# View:

@comments.each_root {
  display @comment {
    indent & recurse on @comment.children 
} }

# alternatives for how recursion call might work:     

# first searches @comments, then actually goes to SQL
comment.in_memory.children

# only looks at @comments, RecordNotFound if not there
# better if we know @comments is complete, and checking for nonexistent
#  records would be wasteful
comment.in_memory(:only).children

# the real thing - goes all the way to DB even though target is already in RAM
# ... but there's no way for find() to realize that :(
comment.children

我什至不确定这是否可能,更不用说一个好主意了,但我很好奇,而且它会很有帮助。

基本上我想重定向 find() ,以便它首先/仅查看已加载的集合,使用类似于假设的 @collection.find{|item| 之类的东西。 item.matches_finder_sql(...)}

重点是防止对已批量加载的内容进行不必要的复杂缓存和昂贵的数据库查找。

如果可能的话,如果这能与现有的过时机制、关联延迟加载等配合得很好,那就太好了。

嵌套注释只是一个例子;当然这也适用于许多其他情况。

那么...我该怎么做呢?

For somewhat complicated reasons, I would like to create something that works like this:

# Controller:
@comments = @page.comments # comments are threaded
# child comments still belong to @page
...  
# View:

@comments.each_root {
  display @comment {
    indent & recurse on @comment.children 
} }

# alternatives for how recursion call might work:     

# first searches @comments, then actually goes to SQL
comment.in_memory.children

# only looks at @comments, RecordNotFound if not there
# better if we know @comments is complete, and checking for nonexistent
#  records would be wasteful
comment.in_memory(:only).children

# the real thing - goes all the way to DB even though target is already in RAM
# ... but there's no way for find() to realize that :(
comment.children

I'm not even sure yet if this is possible, let alone a good idea, but I'm curious, and it'd be helpful.

Basically I want to redirect find() so that it looks first/only at the collection that's already been loaded, using something like a hypothetical @collection.find{|item| item.matches_finder_sql(...)}.

The point is to prevent unnecessarily complex caching and expensive database lookups for stuff that's already been loaded en masse.

If possible, it'd be nice if this played nice with extant mechanisms for staleness, association lazy loading, etc.

The nested-comments thing is just an example; of course this applies to lots of other situations too.

So... how could I do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦幻的心爱 2024-08-14 02:38:59

您不应该编写 Rails 本身已有的内容!您可以轻松地利用 Rails 的缓存方法将查询结果放入 Memcached(或您配置的任何缓存框架)中:

class ArticleController < ApplicationController 
  def index
    @articles = Rails.cache(:articles_with_comments, :expires_in => 30.minutes) do
      Article.find(:all, :include => :comments)
    end
  end
end

顺便说一句。 :expires_in 是可选的。您可以“永远”保留缓存或手动使其过期。

第二个例子,如我的评论所示:

class ArticleController < ApplicationController 
  def index
    @page = Page.find(params[:page_id]

    @articles = Rails.cache([:articles_with_comments, @page.id], :expires_in => 30.minutes) do
      Article.find(:all, :include => :comments, :conditions => { :page_id => @page.id})
    end
  end
end

这将缓存给定 @page 对象的文章和评论。

You should not write something that's already in Rails itself! You can easily leverage Rails' caching methods to put your query results in Memcached (or what ever caching framework you configured):

class ArticleController < ApplicationController 
  def index
    @articles = Rails.cache(:articles_with_comments, :expires_in => 30.minutes) do
      Article.find(:all, :include => :comments)
    end
  end
end

BTW. the :expires_in is optional. You can leave the cache 'forever' or expire it manually.

Second example, as by my comment:

class ArticleController < ApplicationController 
  def index
    @page = Page.find(params[:page_id]

    @articles = Rails.cache([:articles_with_comments, @page.id], :expires_in => 30.minutes) do
      Article.find(:all, :include => :comments, :conditions => { :page_id => @page.id})
    end
  end
end

This will cache the articles and comments for a given @page object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文