[LRUG] Advice: manipulating ActiveRecord objects [newbie]

Marco Iannone marco.iannone at gmail.com
Mon Dec 14 04:46:56 PST 2015


​Hello,

​
Ruby newbie question alert
​: many apologies if it's too basic, or not the type of questions for this
forum.
At least I can say we tried hard before going to StackOverflow
<http://stackoverflow.com/questions/34227034/manipulating-activerecord-objects-to-build-json>
​, and now here.​


We're trying to
​ensure a webpage loads faster. The main issue
​relates to a few activerecord-generated queries on that page.

If you look at the SQL they generate, the queries are as follows (all code
a bit simplified):

select * from feed_details where account_id = 5
select * from feeds where id in (VERY_LONG_LIST_OF_IDS_FROM_FIRST_QUERY)
select * from feeds_metadata where feed_id in
(VERY_LONG_LIST_FROM_FIRST_QUERY)
select * from documents where feed_id in (VERY_LONG_LIST_FROM_FIRST_QUERY)

All the indexes are in place, but we verified that they'd take less than
half the time by changing
​each of them to:

select * from feeds, feed_details where id = feed_id and account_id = 5
select * from feeds_metadata fm, feed_details fd where fm.feed_id =
fd.feed_id and account_id = 5
select * from documents where d, feed_details fd where d.feed_id =
fd.feed_id and account_id = 5

So far, so simple.

Here is the
​Rails issue: these queries have been generated by this code in the
FeedDetail model:

class FeedDetail < ActiveRecord::Base

  has_many :feeds
  has_many :feeds_metadata
  has_many :documents

  scope :feeds_data_for_account, ->(current_account_id) do
    FeedDetail
              .includes(:feeds, :feeds_metadata, :documents)
              .where(
                  account_id: current_account_id
              )
  end

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):

  def index
    consumer          = ConsumerWithAccount.new(current_user.account)
    feed_builder      = FeedBuilder
    feeds_data        = FeedDetail.feeds_data_for_account(
current_user.account.id)

    render json: ResponseBuilder.new(consumer, feed_builder, feeds_data)
  end

To use the faster queries, we were hoping to build the feeds_data
activerecord object
​​by using the faster queries; this gets passed to the JSON builder​. That
would
​seem to require getting rid of the "involves", which (seemingly) uses the
IN ().

If useful, we have the
​more effective activerecord for the 3 queries, they look like:
Feed.joins(:feed_details).where(feed_document_sets: {account_id:
current_account_id})

But we couldn't figure out how to build that
​ ​
​activerecord object
​, or one that can be parsed in a similar way by the responsebuilder​
: therein lies the proverbial rub.

Intense googling and referring to rails docs hasn't helped.​


The plan B
​would be to re-write the responsebuilder to take a different type of
object, but that looks more complicated.

The person who wrote this is no longer with the company.

Plan C is to shake very hard the computer and hope for the best.

Any suggestions would be much appreciated
​, off/on list​
.

​Thanks,
Marco​
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lrug.org/pipermail/chat-lrug.org/attachments/20151214/15c1aca8/attachment.html>


More information about the Chat mailing list