foo_ids 相当于 find_each 吗?

Joh*_*hir 5 ruby ruby-on-rails rails-activerecord

鉴于此模型:

class User < ActiveRecord::Base
  has_many :things
end
Run Code Online (Sandbox Code Playgroud)

然后我们可以这样做::

@user = User.find(123)
@user.things.find_each{ |t| print t.name }
@user.thing_ids.each{ |id| print id }
Run Code Online (Sandbox Code Playgroud)

有很多,@user.things我只想批量迭代它们的 id,就像find_each. 有没有方便的方法来做到这一点?

目标是:

  • 不要thing_ids一次将整个数组加载到内存中
  • 仍然只加载 的数组thing_ids,而不是Thing为每个 id实例化 a

Hal*_*gür 5

Rails 5 引入了in_batches方法,它产生一个关系并在pluck(primary_key)内部使用。我们可以利用where_values_hash关系的方法来检索已经提取的 id:

@user.things.in_batches { |batch_rel| p batch_rel.where_values_hash['id'] }
Run Code Online (Sandbox Code Playgroud)

请注意,in_batches具有orderlimit限制类似于find_each.

这种方法有点笨拙,因为它取决于 的内部实现,in_batches并且如果in_batches将来停止提取 id将会失败。一个非 hacky 方法是batch_rel.pluck(:id),但这会运行相同的 pluck 查询两次。