В моем простом приложении для участия есть :students
, :semesters
, :attendances
. Посещаемость имеет столбцы student:references semester:references date:date present:boolean
.предварительно загруженный вложенный ресурс с условием
semester.rb
class Semester < ApplicationRecord
has_and_belongs_to_many :students
accepts_nested_attributes_for :students
end
student.rb
class Student < ApplicationRecord
has_and_belongs_to_many :semesters
has_many :attendances, dependent: :destroy
accepts_nested_attributes_for :attendances
end
attendance.rb
class Attendance < ApplicationRecord
belongs_to :semester
belongs_to :student
validates_presence_of :date
end
В semesters#show
страницы, я хочу, чтобы отобразить каждый студент в этом семестре, и процент посещаемости каждого учащегося, как показано ниже.
Это работает, но я должен фильтровать через некоторое :attendances
, которые не связаны с семестре, прежде чем начать отсчет. Поэтому моя цель - загрузить семестр, его учеников и их посещаемость, которые принадлежат только этому семестру.
Таким образом, когда я использую
@semester.students.each do |student|
student.attendances
end
Метод .attendances
должен возвращать только те, которые связаны с этим семестре. Это возможно?
Вот что я получил
# semesters_controller.rb
def show
@semester = Semester.includes(students: [:attendances])
.order('students.first_name')
.find params[:id]
end
# students_helper.rb
def student_attendance(student)
total = student.attendances.select { |x| x.semester_id == @semester.id }
present = total.select &:present
percent = (present.size/total.size.to_f * 100).round rescue 0
link_to student, class: 'attendance', style: "width: #{percent}%" do
<<-HTML.html_safe
<span>#{student.first_name}</span>
<span>#{percent}%</span>
HTML
end
end
Я обнаружил, что использование select {|x| x.semester_id == @semester.id }
вместо where semester_id: @semester.id
и select &:present
вместо where present: true
уменьшает количество запросов.
В любом случае, есть ли способ, которым я могу загрузить :attendances
, так что мне не нужно проходить через этот первый фильтр (select {|x| x.semester_id == @semester.id }
)? Если я не фильтрую, как я делаю, тогда он покажет процент посещаемости учащегося для ВСЕХ семестров, в которых они когда-либо были, а не только в этом семестре, который мы пытаемся показать на странице #show.
Я просто не хочу загружать все ненужные данные, а что значит? Благодарю.