Andrii Furmanets
Andrii Furmanets

Reputation: 1161

How to speed up AR query

Let's have a look at the following code:

users = []

User.find_each do |u|
 author = u.articles.where('some where statement').limit(1).try(:author)
 users << { user: u.name, author: author }
end

users

The problem is when I iterate on each User and Active Record make a call to DB.

I've tried includes for articles but it only loads all articles and then make a select from DB, because of where, limit and author.

Any ideas how can I avoid to many calls to DB, may be somehow preload articles with whole conditions?

Upvotes: 0

Views: 57

Answers (2)

apneadiving
apneadiving

Reputation: 115541

A quick setup would be:

User.includes(articles: :author).joins(:articles).merge(Article.where('some where statement')).map do |u|
  { user: u.name, author: u.articles.first.author }
end

But its useless to load all articles to only take one, so you could define a dedicated relationship if 'some where statement' is fixed.

Upvotes: 0

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230561

As far as I can tell, you want one article per user. So, group by naturally comes to mind. Something along these lines should work:

articles = Article.includes(:user, :author).where(your_where_condition).group(:user_id)
users = articles.map{|a| { user: a.user.name, author: a.author }}

Upvotes: 4

Related Questions