Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 4: small N+1 issue for uncached page

I have a some code that is generating an N+1 database querying issue.

The issue only occurs if the page is uncached. Once the page is cached, adding an .includes actually results in an unnecessary database call. I'm wondering how to get around this problem.

my applicaiton_helper.rb contains the following:

module ApplicationHelper
  def by(article)
    "By #{article.username} on #{article.created_at.strftime('%B %e, %Y')}"
  end
end

my article.rb contains:

class Article < ActiveRecord::Base
  belongs_to :user

  def username
    user.username
  end
end

and my articles_controller.rb contains:

class ArticlesController < ApplicationController
  def index
    @articles = user_signed_in? ? Article.all : Article.all.published.limit(13)
  end
end

The method in question is the username method, which makes a call to the User model. As aforementioned, when the page hasn't already been cached, this results in the by(article) helper method to make continuous calls to the User model without any eager loading. However, since I am caching my views, this inefficiency only occurs once. If I change my articles_controller.rb to the following:

class ArticlesController < ApplicationController
  def index
    @articles = user_signed_in? ? Article.all.includes(:user) : Article.all.published.limit(13).includes(:user)
  end
end

the N+1 issue disappears on the first page load, but then I get an unnecessary .includes upon reloading the page.

Any idea how I can fix this small glitch?

Thanks!

like image 771
DaniG2k Avatar asked Jan 06 '16 11:01

DaniG2k


1 Answers

Somehow this has solved my problem:

class Article < ActiveRecord::Base
  belongs_to :user
  delegate :username, to: :user
end

So I simply delegate the username call on an article to the User model. Beautiful, clean and does the trick: bullet no longer complains.

like image 109
DaniG2k Avatar answered Oct 20 '22 14:10

DaniG2k