作爲優化的一部分,我們不我們整個User
存儲在會話,而不是我們包裹User
僅包含基本屬性的門面內,如id
,username
和admin?
。其他任何東西都是延遲加載的(使用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
的調用,就像我期望的那樣。