2009-10-04 26 views
2

對於比較複雜的原因,我想創造的東西,是這樣的:在哪裏補丁Rails ActiveRecord :: find()首先檢查內存中的集合?

# 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(...)}

重點是防止不必要的複雜緩存和昂貴的數據庫查找的東西,已被加載整體。

如果可能的話,這將會是好的,如果這個打了現存機制陳舊,關聯延遲加載等

的嵌套評論的事情僅僅是一個很好的例子;當然這也適用於很多其他情況。

那麼......我該怎麼做?

回答

1

你不應該寫一些已經在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 

BTW。 :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對象的文章和評論。

+0

作爲額外的好處,您可以使用緩存鍵的數組。這個鍵可能包含'動態'變量。我添加了第二個例子。 – Ariejan 2009-10-04 20:03:52

+0

這不會做我想做的事,因爲它不允許我繼續使用標準的查找和查找使用方法(如來自awesome_nested_set的.children)。問題不是緩存問題(比如你的問題),而是更多的代理問題。 – Sai 2009-10-10 06:29:05