在我简单的出勤应用程序中,有: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
Attenance.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页面上显示的这一学期。我只是不想加载所有不必要的数据,不是吗?谢谢。
最佳答案
看来您已经有一种方法可以将出勤与学期直接联系起来(如出勤课程中所述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查询)
关于mysql - 带条件预加载嵌套资源,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42355335/