在一个RSpec测试中,我创建了一个记录,其中有几个memoized值。foo.reload按照对象属性的预期工作,但记忆化的属性仍然存在。到目前为止,它的工作原理是完全重新创建对象:foo = Foo.find(123)但在我的例子中,查找记录的逻辑实际上更复杂。什么是一个好的,干燥的方式完全重新加载记录和删除所有的记忆值?
foo.reload
foo = Foo.find(123)
vsmadaxz1#
你可以通过重新定义reload来实现。例如,如果你使用||=进行memoized,你可以这样做:
reload
||=
class Foo < ActiveRecord::Base def bar @bar ||= rand end def reload(options = nil) @bar = nil super end end
有关重置所有示例变量的方法,请参见Is there a clean API for resetting instance variables on 'reload' in ActiveRecord?如果你使用memoist gem,你可以在这里调用flush_cache。
flush_cache
bvpmtnay2#
Michael的回答是合理的,但要注意,如果您使用the more sophisticated pattern for also memoization nil and false values,这将不会重置备忘录。例如,使用文章中的相同示例存储nil和false值:
nil
false
def main_address return @main_address if defined? @main_address @main_address = begin main_address = get_home_address_from_api main_address ||= get_work_address_from_api main_address ||= another_api_call.first end end
这个模式很好用,因为它还存储了nil和false,但是当然,要重置它,简单地将@main_address设置为nil是不够的,因为它已经被定义并提前返回。在这些情况下,您应该像这样重置它:
@main_address
def reset_main_address_memoization self.send(:remove_instance_variable, :@main_address) if instance_variable_defined?(:@main_address) end
ffscu2ro3#
好的方法是你已经拥有的:完全重新创建对象。你不能用任何简单的“Rails”方式“重新加载”对象的记忆值,因为记忆属性不是Rails或ActiveRecord的功能,它们都不知道你如何记忆方法。
3条答案
按热度按时间vsmadaxz1#
你可以通过重新定义
reload
来实现。例如,如果你使用||=
进行memoized,你可以这样做:有关重置所有示例变量的方法,请参见Is there a clean API for resetting instance variables on 'reload' in ActiveRecord?
如果你使用memoist gem,你可以在这里调用
flush_cache
。bvpmtnay2#
Michael的回答是合理的,但要注意,如果您使用the more sophisticated pattern for also memoization
nil
andfalse
values,这将不会重置备忘录。例如,使用文章中的相同示例存储
nil
和false
值:这个模式很好用,因为它还存储了
nil
和false
,但是当然,要重置它,简单地将@main_address
设置为nil
是不够的,因为它已经被定义并提前返回。在这些情况下,您应该像这样重置它:
ffscu2ro3#
好的方法是你已经拥有的:完全重新创建对象。
你不能用任何简单的“Rails”方式“重新加载”对象的记忆值,因为记忆属性不是Rails或ActiveRecord的功能,它们都不知道你如何记忆方法。