2011-05-20 27 views
1

作爲優化的一部分,我們不我們整個User存儲在會話,而不是我們包裹User僅包含基本屬性的門面內,如idusernameadmin?。其他任何東西都是延遲加載的(使用method_missing)。將此對象寫入會話時,會在編組之前卸載用戶。資源路徑如何工作(內部)?意外的行爲,我需要修復

基本上是:

class UserProxy 
    attr_reader :id 
    attr_reader :username 

    def initialize(user) 
    @user = user 
    reload_attributes! 
    end 

    def admin? 
    @admin 
    end 

    def self.model_name 
    User.model_name 
    end 

    def method_missing(meth, *args, &block) 
    @user ||= User.get!(id) 
    @user.send(meth, *args, &block) 
    ensure 
    reload_attributes! # seems as good a place as any to keep the data fresh 
    end 

    def unset_user! 
    @user = nil 
    self 
    end 

    def ==(*args, &block) 
    method_missing('==', *args, &block) 
    end 

    def !=(*args, &block) 
    method_missing('!=', *args, &block) 
    end 

    def self._load(data) # custom unmarshalling logic 
    UserProxy.new(ActiveSupport::JSON.decode(data)).unset_user! 
    end 

    def _dump(depth) # custom marshalling logic 
    reload_attributes! 
    ActiveSupport::JSON.encode({"id" => id, "username" => username, "admin" => admin}) 
    end 

    private 

    def reload_attributes! 
     return if @user.nil? 

     @id = @user["id"] 
     @username = @user["username"] 
     @admin = @user["admin"] 
    end 
end 

這個偉大的工程隨處可見(它的行爲就像它封裝了DataMapper的用戶和我們沒有打數據庫來獲取大多數頁面請求的用戶,因爲重要的位(密鑰和用戶名)已經被加載。

什麼也不能很好地一起玩,是路徑傭工Rails的創建。

<%= url_for(@user) # should be /users/1234 %> 

最初,它會出錯很糟糕,因爲它無法弄清楚model_name是什麼,所以我通過將類方法model_name添加到我的UserProxy類中,並剛剛返回User.model_name來解決此問題,它現在找到了正確的路由,但它取代了用戶ID,它將:

<a href="https://stackoverflow.com/users/%23%3CUserProxy:0xa4449cc%3E">Chris Corbyn</a> 

我不確定在哪裏尋找解決這一問題。我已經在method_missing中調試調用,以查看正在調用的內容,但它甚至沒有收到對to_param的調用,就像我期望的那樣。

回答

3

我不敢相信我沒有試過這個。我只是將to_param添加到代理並將調用委託給用戶對象,並且它可以工作。我沒有意識到Rails中的所有對象都有to_param方法,不管有沒有。那麼我應該爲to_key做同樣的事情!