【问题标题】:Ensure that each instance of a model in Rails exists at most once in memory确保 Rails 中模型的每个实例在内存中最多存在一次
【发布时间】:2014-02-10 13:56:51
【问题描述】:

假设我的 ActiveRecord 模型中有一个 User 类,并且当用户登录时我将用户对象存储在会话中。(即session[:user] = user

在我的代码中的某个时刻,我可能会从数据库中加载同一个用户并对其进行更新。

user = User.where(happy: false).first
user.happy = true
user.save

但是会话中的用户不是最新的,因为session[:user] 是对内存中另一个用户实例的引用。

如果 ActiveRecord 查询方法尽可能从内存中加载 User 的实例(可能使用 ObjectSpace),这将解决问题,但为了避免 XY problem,有什么更好的方法来解决这个问题? 每个控制器运行时重复刷新会话中每个对象的最佳方法是什么?我应该避免在会话中存储对象以支持对象 ID 吗?

【问题讨论】:

  • ActiveRecord 曾经有一个可选的身份映射,但 "Rails 4.0 has removed the identity map from Active Record, due to some inconsistencies with associations"。我建议不要使用这样的会话,如果您在某处需要用户,请将其传递到调用链中或尝试确保仅在尽可能小的范围内使用该用户。
  • 您的意思是建议您在需要时从数据库中加载用户(例如,通过将其 id 存储在会话中)而不是直接存储对象?
  • 或者在你的控制器中使用通常的current_user 方法。然后,如果您怀疑有人在您背后更改了底层用户,请手动 reload 它。我只将 ids 放在任何持久化的东西中,并尽可能避免隐藏的全局变量(session 甚至 current_user 的真正含义)。

标签: ruby-on-rails activerecord


【解决方案1】:

在会话存储中存储对象是bad idea, as explained in this response

所以您猜测存储 id 是正确的,这是正确的做法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多