eager_load
仅选择某些列,但我面临着它取消我的“选择”的问题。
型号:
class Timeline < ActiveRecord::Base
belongs_to :timeline_category, foreign_key: :timeline_category_id
belongs_to :user, foreign_key: :user_id
scope :with_relations, -> { eager_load(:timeline_category).eager_load(:user).order(created_at: :desc)
end
查询:
Timeline.select('timelines.*, users.username, timeline_categories.icon').eager_load(:timeline_category).eager_load(:user)
我也尝试过:
Timeline.select('timelines.*, users.username, timeline_categories.icon').with_relations
由于某种原因,它不断选择所有 3 个表的所有列。我该如何解决它?
Rails 5 引入了 left_outer_joins 方法。所以终于可以了:
Timeline.left_outer_joins(:timeline_category, :user)
.select('timelines.*, users.username, timeline_categories.icon')
长期以来一直想要一种方法来修剪 #includes 和 #eager_load 的 SELECT 列表。今天终于坐下来弄清楚了,它已经作为我维护的数据相关宝石的一部分发布了,The Brick。
通过像这样覆盖
ActiveRecord::Associations::JoinDependency.apply_column_aliases()
,然后当您添加.select(...)
时,它可以充当过滤器来选择构建哪些列别名。
加载
gem 'brick'
后,为了启用此选择性行为,请将特殊列名称 :_brick_eager_load
添加为 .select(...)
中的第一个条目,这会在构建别名时打开列过滤。这是一个例子:
Employee.includes(orders: :order_details)
.references(orders: :order_details)
.select(:_brick_eager_load,
'employees.first_name', 'orders.order_date', 'order_details.product_id')
由于外键对于正确关联所有内容至关重要,因此它们会自动添加,因此您无需将它们包含在选择列表中。
欢迎对此方法提供任何反馈——希望它可以节省您的查询时间和一些 RAM!
我不确定这是否可能,但你可以这样做:
relation = TimeLine.joins(:timeline_category, :user).select('users.username AS username, timeline_categories.icon AS categories_icon')
然后使用
relation.each{ |timeline| puts "username: #{timeline.username} and icon: #{timeline.categories_icon}" }
获取这些字段