2017-02-20 2 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.id и select &:present вместо where present: true уменьшает количество запросов.

В любом случае, есть ли способ, которым я могу загрузить :attendances, так что мне не нужно проходить через этот первый фильтр (select {|x| x.semester_id == @semester.id })? Если я не фильтрую, как я делаю, тогда он покажет процент посещаемости учащегося для ВСЕХ семестров, в которых они когда-либо были, а не только в этом семестре, который мы пытаемся показать на странице #show.

Я просто не хочу загружать все ненужные данные, а что значит? Благодарю.

ответ

1

Похоже, у вас уже есть способ подключения посещаемости непосредственно к семестру (поскольку belongs_to :semester указан в вашем классе Attendance).

Вы пробовали:

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

ИЛИ просто:

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

(вы можете использовать соответствующий подключение/включает в себя, чтобы уменьшить SQL-запросы)