I have an association between Students and Attendances and I would like to query for all students and associated attendance records for a particular date range, including students that don't have any attendance records in that date range (e.g. to build an attendance table for a particular week).
class Student < ActiveRecord::Base
has_many :attendances
scope :with_attendances_for_week_of, lambda { |d|
includes(:attendances).joins("LEFT OUTER JOIN attendances ON (student.id = attendances.student_id AND attendances.date BETWEEN #{(d-d.cwday+1)} AND #{(d-d.cwday+7)})")
}
end
class Attendance < ActiveRecord::Base
belongs_to :student
scope :for_week_of, lambda {|d| where(:date => (d-d.cwday+1)..(d-d.cwday+7)}
end
What I'd like is a way to accomplish something like:
Student.with_attendances_for_week_of(params[:date) do |student|
display_attendance_row student.name, student.attendances
end
I seem to be stuck choosing between solutions that query for ALL past attendance records, or N+1 solutions (where I query student.attendances.for_week_of(params[:date]) for each student).
Simpler scopes like the following only returned students that have attendance records in the date range.
scope :with_attendances_for_date_range, lambda { |date_range|
includes(:attendances).where(:attendances => {:date => date_range})
}
At this point I'd take any solution that doesn't lead to N+1 or querying for thousands of unneeded Attendance records.