从 rails 中的预加载对象获取数据

Get data from the eager loaded object in rails

我试图在同一个查询中从对象中获取数据的同时急切加载对象。查询如下 CycleDay.includes(:user).where(test_required: true, date: Date.today).where.not( :users => { :reader_id => nil }).pluck(:user_id, :users)

在这里,我很想加载 CycleDay belongs_to :user

中的用户对象

查询工作正常,它返回一个由值 [id, {user}] 组成的映射,但我想获取 user.name(用户对象的名称列)而不是用户).是否可以在单个查询中执行此操作?

能够使用以下方法完成此操作,但仍然需要解释,因为我是 rails

的新手
CycleDay.includes(:user).where(test_required: true, date: Date.today).where.not( :users => { :reader_id => nil }).pluck(:user_id, 'users.name')

即使用 'users.name' 而不是 :user

更新:您已经回答了自己的问题。一个小提示,你现在 return 一个数组而不是 ActiveRecord::Relation。这意味着您不能再查询它(或应用另一个范围)。

只是为了解释 ActiveRecord::Relation:

example_collection = CycleDay.joins(:user).select('cycle_days.id, users.name AS user_name').where(test_required: true, date: Date.today).where.not( users: { reader_id: nil })

这个 return 是一个 ActiveRecord::Relation 和一堆对象,只包含一个 id 和 user_name,因为这就是你在查询中 select 的内容。所以现在我可以这样称呼:

example_collection.first.id
example_collection.first.user_name

pluck() 将对象集合转换为数组,并 returns 所选属性的结果。您现在可以在一个数组中看到所有的 ID 和名称,这真的很方便。但是,您现在有一个数组,因此您可以调用它的方法与 ActiveRecord::Relation.

不同

另一个边注,关于加入与包含。举个例子:

example_with_includes = CycleDay.includes(:user).where(test_required: true, date: Date.today).where.not( :users => { :reader_id => nil }).pluck(:user_id, :users)

example_with_includes.each do |cycle_day|
  cycle_day.user.name
end

如果没有包含,您将有一个单独的查询来获取属于该周期日的单个用户的名称。但是,包括预加载的所有用户,因此不需要进一步查询。因此,如果您想在关联对象上调用方法,您应该使用 includes。

如果您不需要对关联对象调用任何方法,则可以使用联接。示例:

  example_with_joins = CycleDay.joins(:user).where(users: { role: 'admin' })

假设您只对循环日的属性感兴趣,那么就没有理由加载整个关联 table。用户现在是所谓的延迟加载,如果你调用它的方法(例如,检索它的名字),你只有额外的查询。