Reputation: 283
I have a rails application where I have following models.
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
I have a query as follows
@booking_hotel_partner_details = BookingHotelPartnerDetail.unscoped.select(:id, :booking_hotel_id, :partner_booking_hotel_id).includes(booking_hotel: :hotel_picture_partners)
This puts memory under pressure as it loads all data for included models.
Is there a way I can only load selective fields from booking_hotels & hotel_picture_partners tables ?
Also I want to get an activerecord array as response.
Upvotes: 1
Views: 139
Reputation: 399
Your project is probably already pretty far along, but for anyone else wanting this behaviour I've released a patch that filters columns if you have a .select(...)
along with .includes(...)
or .eager_load(...)
.
It's now included in a data-related gem I maintain, The Brick.
It works by overriding ActiveRecord::Associations::JoinDependency.apply_column_aliases()
like this.
In order to enable this selective behaviour, add the special column name :_brick_eager_load
as the first entry in your .select(...)
, which turns on the filtering of columns while the aliases are being built out. Here's an example based on your code:
@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')
Feel free to add myraid additional columns from any table as strings in the same way as the last two sample items I put into the .select(...)
.
Because foreign keys are essential to have everything be properly associated, they are automatically added, so you do not need to include :booking_hotel_id
in your select list.
Hope it can save you both query time and some RAM!
Upvotes: 0
Reputation: 2197
pluck
method loads only attributes, without loading whole models. check it: http://apidock.com/rails/ActiveRecord/Calculations/pluck.
Try to rewrite it like this:
BookingHotelPartnerDetail.unscoped.select('booking_hotels.id as bh_id', 'hotel_picture_partners.id as hpp_id').joins(booking_hotel: :hotel_picture_partners)
Upvotes: 1