ruby-on-rails rails包含查询为包含的模型加载整个数据

plicqrtu  于 2022-11-26  发布在  Ruby
关注(0)|答案(2)|浏览(113)

我有一个Rails应用程序,其中包含以下模型。

BookingHotel
    has_many :hotel_picture_partners, through: :hotel_pictures
    has_many :booking_hotel_partner_details, dependent: :destroy

BookingHotelPartnerDetail
    belongs_to :booking_hotel

HotelPicturePartner
    belongs_to :hotel_picture, dependent: :destroy

我有一个查询如下

@booking_hotel_partner_details = BookingHotelPartnerDetail.unscoped.select(:id, :booking_hotel_id, :partner_booking_hotel_id).includes(booking_hotel: :hotel_picture_partners)

这会在加载包含的模型的所有数据时使内存承受压力。
有没有办法只能从booking_hotels & hotel_picture_partners表中加载选择性字段?
我还想得到一个activerecord数组作为响应。

zwghvu4y

zwghvu4y1#

pluck方法只加载属性,而不加载整个模型。检查它:http://apidock.com/rails/ActiveRecord/Calculations/pluck
试着重写如下:BookingHotelPartnerDetail.unscoped.select('booking_hotels.id as bh_id', 'hotel_picture_partners.id as hpp_id').joins(booking_hotel: :hotel_picture_partners)

egmofgnx

egmofgnx2#

您的项目可能已经进行了很久了,但是对于其他想要这种行为的人,我发布了一个补丁,如果您有.select(...)以及.includes(...).eager_load(...),它可以过滤列。
它的工作原理是重写ActiveRecord::Associations::JoinDependency.apply_column_aliases(),如下所示
为了启用这种选择性行为,请添加特殊列名:_brick_eager_load作为.select(...)中的第一个条目,这样在构建别名时会启用列过滤。

@booking_hotel_partner_details =
  BookingHotelPartnerDetail.unscoped
                           .includes(booking_hotel: :hotel_picture_partners)
                           .select(:_brick_eager_load, :id, :partner_booking_hotel_id, 'booking_hotel.name', 'hotel_picture_partners.notes')

您可以自由地从任何表中添加myraid附加列作为字符串,方法与我放入.select(...)的最后两个示例项相同。
因为外键对于正确关联所有内容是必不可少的,所以它们会自动添加,因此您不需要在选择列表中包括:booking_hotel_id
希望它可以保存您的查询时间和一些内存!

相关问题