2017-02-20 77 views
0

在我的简单出勤应用程序中,有: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页,我想显示在那个学期每个学生,每个学生的出勤率如下。

attendance

它的工作原理,但我通过一些: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.idselect &:present代替where present: true缩短了查询的数量。

总之,有没有一种方法可以加载:attendances,这样我就不必经过第一个筛选器(select {|x| x.semester_id == @semester.id })?如果我不像我在做的那样过滤,那么它会显示他们曾经参加过的所有学期的学生出勤率,而不是我们试图在#show页面上显示的这一个学期。

我只是不想加载所有不必要的数据,是不是?谢谢。

回答

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查询)