2017-02-20 5 views
0

In meiner einfachen Anwesenheit App gibt es :students, :semesters, :attendances. Die Anwesenheit hat Spalten student:references semester:references date:date present:boolean.verschachtelte Ressource mit Bedingung laden

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 

In der semesters#show Seite, möchte ich in diesem Semester jeden Schüler anzuzeigen, und der Prozentsatz der Teilnahme pro Schüler wie unten.

attendance

Es funktioniert, aber ich habe durch einige :attendances zu filtern, die nicht mit dem Semester zugeordnet sind, bevor ich Zählung beginnen. Mein Ziel ist es also, das Semester, seine Studenten und deren Studienbesuche, die nur zu diesem Semester gehören, aufzufrischen.

diese Weise, wenn ich

@semester.students.each do |student| 
    student.attendances 
end 

Die .attendances Methode gibt nur die mit diesem Semester verbunden sind, sollten verwendet werden. Ist das möglich?

Hier ist, was habe ich

# 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 

Ich habe festgestellt, dass die Verwendung select {|x| x.semester_id == @semester.id } statt where semester_id: @semester.id und select &:present statt where present: true die Anzahl der Abfragen reduziert.

Wie auch immer, gibt es eine Möglichkeit, dass ich die :attendances laden kann, so dass ich nicht durch den ersten Filter (select {|x| x.semester_id == @semester.id }) gehen muss? Wenn ich nicht filtere, wie ich es tue, dann wird es zeigen, dass die Anwesenheitsquote der Studenten für ALLE Semester, in denen sie jemals waren, statt nur dieses eine Semester, das wir versuchen, auf der #show Seite zu zeigen.

Ich will einfach nicht alle unnötigen Daten laden, nah? Vielen Dank.

Antwort

1

Sieht aus, als ob Sie bereits eine Möglichkeit haben, eine Anwesenheit direkt mit einem Semester zu verbinden (wie belongs_to :semester in Ihrer Anwesenheitsklasse angegeben ist).

Haben Sie versucht:

class Semester < ApplicationRecord 
    has_and_belongs_to_many :students 
    has_many :attendences 
end 
attendences = @semester.attendences 

oder einfach:

attendences = Attendence.where(semester: params[:id]) 

(Sie entsprechende Verknüpfungen verwenden können/includes SQL-Abfragen zu reduzieren)

Verwandte Themen