有效地迭代和变异关联 [英] Efficiently iterate and mutate an association

查看:62
本文介绍了有效地迭代和变异关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有有效执行此操作的代码.

We have code that is effectively doing this.

obj.things.each |thing|
    ... do some stuff ...

    obj.things.destroy(thing)

    ... do some more stuff...
end

我们发现,在迭代CollectionProxy的同时更改CollectionProxy的结果是,只有一半的项目被迭代.目前,我们正在通过将代理展平为一个数组来解决此问题.但这意味着将所有物品复制到内存中.

We found out that simultaneously iterating over a CollectionProxy while changing the CollectionProxy results in only half the items being iterated over. Currently we're working around this by flattening the proxy into an array. But this means copying all the things into memory.

obj.things.to_a.each |thing|
    ...
end

是否有一种方法可以在不将整个关联放入内存的情况下迭代和变异集合?

Is there a way to iterate and mutate through a collection without pulling the entire association into memory?

或者,是否有比我们正在使用的模式更好的模式?例如,包装代码是我们每次破坏关联时都不想做的事情,因此我们不使用关联钩子.我们可以编写一个可以使用钩子的子类或范围吗?

Alternatively, is there a better pattern than the one we're using? For example, the wrapping code are things we don't want to do every time we destroy an association, so we're not using association hooks. Could we write a subclass or scope that can use hooks?

UPDATE :我已经发布有关较大问题的信息.

推荐答案

您原来的每个已将整个关联拉入内存.

Your original each is already pulling the entire association into memory.

调用 to_a 来产生额外的数组副本(然后没有变异)确实是一种非常合理的方法.而且并不是特别昂贵:数组是重复的,但实际的对象不是.

Calling to_a to produce an extra copy of the array (which is then free of mutation) is indeed a very reasonable approach. And not particularly expensive: the array is duplicated, but the actual objects are not.

您还可以使用 ActiveRecord :: Base#destroy 代替:

You could also use ActiveRecord::Base#destroy instead:

obj.things.each |thing|
    ... do some stuff ...

    thing.destroy

    ... do some more stuff...
end

由于 obj.things 集合不再了解破坏,因此它将仍然包含全部内容,因此迭代将不受影响.(不过,如果任何一个 stuff 块使用的是 obj.things 的当前内容,这显然是有问题的.)

As the obj.things collection is no longer aware of the destruction, it will still contain the full set of things, and thus the iteration will be unaffected. (This could obviously be problematic if either stuff block is using the current contents of obj.things, though.)

这篇关于有效地迭代和变异关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆