在我的简单出勤应用中,有: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页面上显示。
我只是不想加载所有不必要的数据,是吗?感谢。
答案 0 :(得分:1)
看起来您已经有办法直接将出勤与学期联系起来了(因为belongs_to :semester
已在您的出勤课程中说明。
你试过了吗?
class Semester < ApplicationRecord
has_and_belongs_to_many :students
has_many :attendences
end
attendences = @semester.attendences
或者只是:
attendences = Attendence.where(semester: params[:id])
(您可以使用适当的连接/包括来减少sql查询)