在我的简单出勤应用程序中,有: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页面上显示的这一个学期。
我只是不想加载所有不必要的数据,是不是?谢谢。