How do I eager-load only some of the objects in a has_many relationship?
Basically, I have four objects: Assignment
, Problem
, AssignmentUser
, and ProblemUser
.
#assignment.rb
has_many :problems
has_many :assignment_users
#assignment_user.rb
belongs_to :assignment
belongs_to :user
has_many :problem_users
#problem.rb
belongs_to :assignment
has_many :problem_users
#problem_user.rb
belongs_to :user
belongs_to :problem
belongs_to :assignment_user
attr_accessor :complete #boolean
On a page showing a single assignment, I want to show all of the problems, as well the user's status on each problem, if it exists. (It might not, if this is the first time the user is viewing the page.)
I can't call assignment_user.problem_users
and then snake the problems out like so:
-@assignment_user.problem_users.each do |problem_user|
= check_box_tag "problems[#{problem_user.problem.id}]", 1, problem_user.complete
= link_to problem_user.problem.name, assignment_problem_path(assignment_id => problem_user.problem.assignment_id, :id => problem_user.problem_id)
because there might not be ProblemUser
entries for every Problem
that belongs to an assignment; creating all of those ProblemUser
objects whenever someone creates a Problem
object would be wasteful, so they're only created on the fly.
What I want is to be able to iterate over the Problems
that belong to the particular Assignment
, then for each Problem
, find a ProblemUser
that matches...but without creating an N+1 problem. I could create two arrays, one with all of the problems and one with all of the problem_users, but then I would have to match them up, right? Maybe that's the best way... but any recommendations on best practices are appreciated here.