从 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。用户现在是所谓的延迟加载,如果你调用它的方法(例如,检索它的名字),你只有额外的查询。
我试图在同一个查询中从对象中获取数据的同时急切加载对象。查询如下
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。用户现在是所谓的延迟加载,如果你调用它的方法(例如,检索它的名字),你只有额外的查询。