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!
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With