WhyServices My Company
whysthatso

Preventing n+1 queries due to queries triggered in view templates

Posted on December 16, 2025  //  rails

I am generally trying to prepare as much data as possible in the controller, so that my views do not trigger additional queries, possibly causing n+1 queries in the process.

I just encountered the following case:

An index of students

@students = Roles::Student.includes(:user, enrollments: :course).all

gets iterated over in the index view

<%= turbo_frame_tag "students", target: "_top" do %>
  <ul role="list">
    <%= render partial: "students/student", collection: @students %>
  </ul>
<% end %>

with the help of this partial

<li id="<%= dom_id student %>">

<...>

<% student.current_enrollments.each do |enrollment| %>
  <div>
    <%= enrollment.course_full_title %>
  </div>
<% end %>

</li>

There are two issues i encountered:

student.current_enrollments

def current_enrollments
  enrollments.active
end

Sending current_enrollments to an instance of students sends in turn the scope active to its associated enrollments, causing a query. As the view iterates over all students, this is a typical n+1 case.

As index shows, i do an includes on enrollments, and my assumption was that internally rails would direct active onto that relation proxy.

What i ended up doing was filtering the available eagerly loaded enrollments:

def current_enrollments
  enrollments.reject { |enrollment| !enrollment.state.in?(["registered", "confirmed", "waiting"]) }
end

however, this is tedious to maintain, and a reason why i came up with the active scope in the first place.

Is there an alternative? Or is my architecture Just Crap™?

Turns out

Hey! I'll happily receive your comments via email. Thanks for reading.

Andreas Wagner
freelance System Administrator and Ruby programmer in Tallinn, Estonia