ruby-on-rails Rails 4 -使用eager_load选择

bttbmeg0  于 2022-11-26  发布在  Ruby
关注(0)|答案(3)|浏览(160)

我试图使用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个表的所有列。我该如何修复它?

eoigrqb6

eoigrqb61#

Rails 5引入了left_outer_joins方法,所以它最终成为可能:

Timeline.left_outer_joins(:timeline_category, :user)
        .select('timelines.*, users.username, timeline_categories.icon')
omjgkv6w

omjgkv6w2#

我不确定这是否可行,但你可以这样做:

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}" }得到这些字段

o75abkj4

o75abkj43#

我一直想找到一种方法来修剪#includes和#eager_load的SELECT列表,今天终于找到了,它已经作为我维护的数据相关gem的一部分发布了,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!

相关问题