mysql - RoR - obj.reload 后 after_initialize 回调中的不同 object_id

标签 mysql ruby-on-rails metaprogramming

我已经为我的项目编写了一个扩展 ActiveRecord 模型行为的方法,我已经删除了其中的大部分内容,请考虑以下代码:

class ActiveRecord::Base

  def self.has_translations
    after_initialize :clear_translations_cache

    def clear_translations_cache
      binding.pry
      @_translations = {}
    end
  end
end

基本上,当我从数据库中.reload 实例时,我希望清除@_translations 实例变量,但出于某种原因,在从数据库中获取现有对象后,执行一个方法填充@_translations,然后执行object.reload@_translations仍然包含相同的数据。

我确信当第一次从数据库中获取对象和调用 .reload 时会执行回调。我使用 binding.pry 在回调方法中停止执行,但由于某些原因 .reload 中的 self.object_id 与我的 object_id 不同原始对象,因此原始对象中的 @_translations 不会被清除。

附件是控制台输出:

1.9.3p194 :008 > s = TranslatedItem.first
   76:     def clear_translations_cache
=> 77:       @_translations = {}
   78:     end

[1] pry(#<TranslatedItem>)> self.class
=> TranslatedItem(id: integer, created_at: datetime, updated_at: datetime)
[2] pry(#<TranslatedItem>)> self.object_id
=> 70254243993580
[3] pry(#<TranslatedItem>)> exit
1.9.3p194 :009 > s.object_id
 => 70254243993580
1.9.3p194 :010 > s.reload
   76:     def clear_translations_cache
=> 77:       @_translations = {}
   78:     end
[1] pry(#<ServiceLevel>)> self.class
=> TranslatedItem(id: integer, created_at: datetime, updated_at: datetime)
[2] pry(#<TranslatedItem>)> self.object_id
=> 70254259259120

最佳答案

我猜你看到的行为与 ActiveRecord reload 的方式有关作品:

fresh_object = self.class.unscoped { self.class.find(self.id, options) }
@attributes.update(fresh_object.instance_variable_get('@attributes'))

您会注意到它是通过从数据库中查找对象来创建新对象的,这解释了为什么您在回调方法中看到两个不同的 object_id 值。在重新加载期间初始化的对象仅用于其属性,然后超出范围。

从你的问题中不清楚你是否只是好奇为什么它会这样,或者你是否正在寻找一种替代方法来做到这一点。

更新:

如果您只是在寻找一种在重新加载模型时清除实例变量的方法,那么您有几个选择。

1) 添加您自己的可以显式调用的重新加载方法:

class ActiveRecord::Base
  def reload_everything
    reload
    @_translations = {}
  end
end

object.reload_everything

2) 改变reload的行为

module ReloadTranslations
  def reload(*args)
    super
    @_translations = {}
  end
end

ActiveRecord::Base.send(:include, ReloadTranslations)

关于mysql - RoR - obj.reload 后 after_initialize 回调中的不同 object_id,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12556135/

相关文章:

powershell - 我可以在Powershell中动态找到类的所有子类吗

php - 类型“字符串”是意外参数,应为Mysqli [mysqli_real_escape_string]

php - 提交表单后显示错误信息

php - 从 SQL 表中随机选择 2 行

javascript - 日期选择器 Bootstrap 不保存

c++ - SFINAE : Understanding void_t and detect_if

php - 将 UTF8 名称插入表会出现重复错误

ruby-on-rails - 考虑使用现有数据(不是数据库,实际数据)的新 Rails 应用程序——最好的处理方法是什么?

ruby-on-rails - 保持elasticsearch和数据库同步

c++ - 模板元编程——g++ 吃掉了它,clang 没有