<html><head><style>body{font-family:Helvetica,Arial;font-size:13px}</style></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;"><br></div> <br> <div id="bloop_sign_1450100460210742016" class="bloop_sign"></div> <br><p class="airmail_on">On 14 December 2015 at 12:47:21, Marco Iannone (<a href="mailto:marco.iannone@gmail.com">marco.iannone@gmail.com</a>) wrote:</p> <blockquote type="cite" class="clean_bq"><span><div><div></div><div>



<title></title>


<div dir="ltr">
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">
​Hello,<br>
<br>
​</div>
Ruby newbie question alert
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">
​: many apologies if it's too basic, or not the type of questions
for this forum.<br>
At least I can say we tried hard before going to <a href="http://stackoverflow.com/questions/34227034/manipulating-activerecord-objects-to-build-json">
StackOverflow</a></div>
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">
​, and now here.​</div>
<br>
<br>
We're trying to
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">
​ensure a webpage loads faster. The main issue</div>
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">
​relates to a few activerecord-generated queries on that
page.<br></div>
<br>
If you look at the SQL they generate, the queries are as follows
(all code a bit simplified):<br>
<br>
select * from feed_details where account_id = 5<br>
select * from feeds where id in
(VERY_LONG_LIST_OF_IDS_FROM_FIRST_QUERY)<br>
select * from feeds_metadata where feed_id in
(VERY_LONG_LIST_FROM_FIRST_QUERY)<br>
select * from documents where feed_id in
(VERY_LONG_LIST_FROM_FIRST_QUERY)<br>
<br>
All the indexes are in place, but we verified that they'd take less
than half the time by changing
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">
​each of them to:<br></div>
<br>
select * from feeds, feed_details where id = feed_id and account_id
= 5<br>
select * from feeds_metadata fm, feed_details fd where fm.feed_id =
fd.feed_id and account_id = 5<br>
select * from documents where d, feed_details fd where d.feed_id =
fd.feed_id and account_id = 5<br>
<br></div></div></div></span></blockquote><div><br></div><div><br></div>That in a nutshell is the difference between .preloads and .eager_load (.includes defaults to preloads), except that .eager_load runs one query<div>to load all the associations. This can perform badly when there are multiple has_many being loaded (as in your case) , since you end up pretty much with the cartesian  product. Worth a try though.</div><div><br></div><div><blockquote type="cite" class="clean_bq"><span><div><div><div dir="ltr">This generates an active record object with the data from the
above-mentioned queries, that is used in the controller to build
the JSON that is sent to the webpage as in below (see feeds_data
line):<br>
<br>
  def index<br>
    consumer          =
ConsumerWithAccount.new(current_user.account)<br>
    feed_builder      = FeedBuilder<br>
    feeds_data        =
FeedDetail.feeds_data_for_account(<a href="http://current_user.account.id">current_user.account.id</a>)<br>
<br>
    render json: ResponseBuilder.new(consumer,
feed_builder, feeds_data)<br>
  end<br>
 <br>
To use the faster queries, we were hoping to build the feeds_data
activerecord object
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">
​​by using the faster queries; this gets passed to the JSON
builder​. That would</div>
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">
​seem to require getting rid of the "involves", which (seemingly)
uses the IN ().<br></div>
<br>
If useful, we have the
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">
​more effective activerecord for the 3 queries, they look
like:<br></div>
Feed.joins(:feed_details).where(feed_document_sets: {account_id:
current_account_id})<br>
<br>
But we couldn't figure out how to build that
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">
​ ​</div>
​activerecord object
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">
​, or one that can be parsed in a similar way by the
responsebuilder​</div>
: therein lies the proverbial rub.
<div class="gmail_default" style="font-family:arial,helvetica,sans-serif;font-size:small;display:inline">
<br>
Intense googling and referring to rails docs hasn't helped.​</div>
<br>
<br></div></div></div></span></blockquote><div><br></div><div><br></div></div><div>Sometimes you can crowbar this sort of stuff in: load the objects for each of the tables in whatever way is the fastest, keep them in a hash so that you can easily identify which ones belongs to which feed detail. Then fiddle with some_feed_detail.association(:association_name).target to side load in the data. This may not work if response builder expects to have an active record relation rather than an array (i.e. it wants to chain more stuff onto the scope)</div><div><br></div><div>Fred</div><div><br></div></body></html>