2013-10-09 32 views
1

說我有一個用戶模型。它有一個稱爲狀態的實例方法。狀態不是關聯。它不遵循任何活動的記錄模式,因爲它是一個已經在生產中的數據庫。緩存ActiveRecord模型實例方法

class User < ActiveRecord::Base 

    def status 
    Connection.where(machine_user_id: self.id).last 
    end  

end 

所以我這樣做。

@users = User.all 

首先,我不能急於加載狀態方法。

@users.includes(:status).load 

其次,我不能在用戶數組內緩存該方法。

Rails.cache.write("user", @users) 

狀態方法從未被調用,直到視圖層看起來像。

什麼是緩存此方法的推薦方法。

也許這種實例方法不是我想要做的。我看過範圍,但看起來不像我想要做的。

也許我只是需要一個關聯?然後我得到包括,我可以緩存。

但協會可以處理複雜的邏輯。在這種情況下,實例方法是一個簡單的查詢。如果我在該實例方法中有複雜的邏輯會怎麼樣?

感謝您的任何幫助。

回答

1

你試圖封裝一些純Ruby對象像這裏面的這個邏輯(我不會,雖然使用了非常大的集合):

class UserStatuses 
    def self.users_and_statuses 
    Rails.cache.fetch "users_statuses", :expires_in => 30.minutes do 
     User.all.inject({}) {|hsh, u| hsh[u.id] = u.status; hsh } 
    end 
    end 
end 

這之後你可以用一些輔助的方法來訪問緩存版本

class User < ActiverRecord::Base 
    def cached_status 
    UserStatuses.users_and_statuses[id] 
    end 
end 

它並不能解決你的預先加載的問題時,Rails沒有任何緩存熱身內置技術。但是,通過提取這樣的,它很容易通過在cron運行rake任務來完成。

也在這種情況下,我看不到使用關聯的任何問題。 Rails關聯允許您提交不同的選項,包括外鍵和主鍵。

+0

我實際上已經在做這個。 Rails.cache.read( 「connection_history _#{} self.id」)。我只是用一個查詢來舉例說明。即使它被緩存了,我仍然想要一次性緩存所有內容。加載時間仍然很糟糕,因爲它在每一行都進行緩存提取。 –

+0

你是什麼意思「一次全部緩存」,你還想緩存一個用戶對象? –

+0

我想拋出整個用戶對象與實例方法評估到一個緩存。讀取用戶緩存,而不是讀取用戶緩存,然後在顯示它時讀取緩存狀態的單個緩存。希望這是有道理的。 當然,這往往會出現,然後不。考慮一個名爲full_name的實例方法。它採取名和姓並連接它。我想將User對象放入緩存中,並使用full_name方法進行評估。 –