Mik*_* S. 3 mysql metaprogramming ruby-on-rails
我为我的项目编写了一个扩展ActiveRecord模型行为的方法,我已经删除了大部分内容,请考虑以下代码:
class ActiveRecord::Base
def self.has_translations
after_initialize :clear_translations_cache
def clear_translations_cache
binding.pry
@_translations = {}
end
end
end
Run Code Online (Sandbox Code Playgroud)
基本上,我想,当我@_translations实例变量得到清除.reload的情况下从数据库中,但由于某些原因,从数据库中获取现有对象,执行该填充的方法后@_translations,再执行object.reload,@_translations仍然包含相同的数据.
我确信在第一次从数据库中获取对象和调用时会执行回调.reload.我使用binding.pry来停止回调方法中的执行,但由于某种原因,self.object_id内部与我的原始对象.reload不同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
Run Code Online (Sandbox Code Playgroud)
我猜你所看到的行为与ActiveRecord重新加载的工作方式有关:
fresh_object = self.class.unscoped { self.class.find(self.id, options) }
@attributes.update(fresh_object.instance_variable_get('@attributes'))
Run Code Online (Sandbox Code Playgroud)
您会注意到它是通过从数据库中查找它来创建一个新对象,这解释了为什么您在回调方法中看到两个不同的object_id值.在重新加载期间初始化的对象仅用于其属性,然后超出范围.
从你的问题中不清楚你是否只是好奇它为什么会这样做,或者你是否正在寻找另一种方法来做到这一点.
更新:
如果您只是在重新加载模型时正在寻找清除实例变量的方法,那么您有几个选项.
1)添加您可以显式调用的自己的重载方法:
class ActiveRecord::Base
def reload_everything
reload
@_translations = {}
end
end
object.reload_everything
Run Code Online (Sandbox Code Playgroud)
2)改变重载的行为
module ReloadTranslations
def reload(*args)
super
@_translations = {}
end
end
ActiveRecord::Base.send(:include, ReloadTranslations)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
195 次 |
| 最近记录: |