作为优化的一部分,我们不会将整个User
存储在会话中,而是将User
包含在仅包含基本属性的Facade中,例如{{1} },id
和username
。其他任何东西都是延迟加载的(使用admin?
)。将此对象写入会话时,它会在编组之前卸载用户。
基本上:
method_missing
这在任何地方都很有效(它的行为就像它包装的DataMapper用户一样,我们不必点击数据库就可以让用户获得大多数页面请求,因为已经加载了重要的位(密钥和用户名)。 / p>
它不能很好地发挥作用,是Rails创建的路径助手。
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
最初它会出错,因为它无法弄清楚<%= url_for(@user) # should be /users/1234 %>
是什么,所以我通过将类方法model_name
添加到我的model_name
类并且只返回{ {1}}它现在找到了正确的路由,但是代替用户ID,它放置:
UserProxy
我不确定在哪里修理这个。我已经在method_missing中调试调用以查看正在调用的内容,但它甚至没有接收到User.model_name
的调用,就像我期望的那样。
答案 0 :(得分:3)
我简直不敢相信我没试过。我刚刚将to_param
添加到代理并将调用委托给用户对象并且它可以正常工作。我没有意识到Rails中的所有对象都有to_param
方法,模型与否。我应该对to_key
然后做同样的事情!