I have several models that are all linked together in a time
tracking/billing system ala:
class Claim < AR::B
has_many :appointments
def student
@student ||= Student.joins(student_appointments:
:claim).where(’claims
.id
=
?’,self.id).group(’students
.id
’).first
#second draft
# @student ||= (student_appointments.size == 0 ? nil :
student_appointments[0].student) #first draft
end
end
class Appointment < AR::B
belongs_to :claim
belongs_to :student
end
class Student < AR::B
has_many :appointments
end
My users that administer these accounts want to be able to look at
claims
in the index but need to know who these claims were for. My first
attempt
building the view resulted in 2*N + 1 queries for getting the student’s
name, the second implementation paired that down to N+1 but obviously
that
still sucks. To totally avert the N+1 query problem typically I’d just
eager load what I needed via Claim.includes(:appointments => :student)
but
I’d really like to avoid this here since I’ll never actually use the
appointments in the view. I’ve tried a has_one :through but rails
doesn’t
allow a collection to then point at a single record this way, I’ve also
tried just loading them via: Student.joins(‘join through to
claims’).where(claims.id in (?),claims.map(&:id)) in the
presenter/controller but since everything is lazy loaded the query never
gets executed and then the N+1 loads start. The third though I had was
doing a belongs_to with conditions but there isn’t any way to include
joins
in there so that’s out. My last thought is to do something like:
class Claim < AR::B
has_many :appointments
has_one :appointment
has_one :student, :through => :appointment
end
but that clutters up the methods and would leave us open to the mistake
of
looking for the collection and getting the single. Are there any
suggestions out there aside from loading the whole tree?