improve teacher count in courses api

don't double-count enrollments in multiple sections
in the same course

closes #ADMIN-2601

Change-Id: Ia3710feba7d6c32aa32f1be4c08c3822cafc31b9
Reviewed-on: https://gerrit.instructure.com/190144
Tested-by: Jenkins
Reviewed-by: Rob Orton <rob@instructure.com>
QA-Review: Rob Orton <rob@instructure.com>
Product-Review: Rob Orton <rob@instructure.com>
This commit is contained in:
James Williams 2019-04-22 08:28:51 -06:00
parent b12380bce5
commit d234d60142
2 changed files with 18 additions and 1 deletions

View File

@ -174,7 +174,8 @@ module Api::V1::Course
def preload_teachers(courses)
threshold = params[:teacher_limit].presence&.to_i
if threshold
teacher_counts = Course.where(:id => courses).joins(:teacher_enrollments).group("courses.id").count
scope = TeacherEnrollment.active_or_pending.where(:course_id => courses).distinct.select(:user_id, :course_id)
teacher_counts = Enrollment.from("(#{scope.to_sql}) AS t").group("t.course_id").count
to_preload = []
courses.each do |course|
next unless count = teacher_counts[course.id]

View File

@ -705,6 +705,22 @@ describe "Accounts API", type: :request do
expect(c2_hash['teacher_count']).to eq 2
end
it "should return a better teacher count if a teacher is in too many sections" do
@c1 = course_with_teacher(:account => @a1, :course_name => 'c1').course
s2 = @c1.course_sections.create!
# should not think there are two teachers if one is in multiple sections
@c1.enroll_teacher(@teacher, :section => s2, :allow_multiple_enrollments => true)
@c2 = course_with_teacher(:account => @a1, :course_name => 'c2', :user => @teacher).course
@a1.account_users.create!(user: @user)
json = api_call(:get, "/api/v1/accounts/#{@a1.id}/courses?include[]=teachers&teacher_limit=1",
{ :controller => 'accounts', :action => 'courses_api', :account_id => @a1.to_param,
:format => 'json', :include => ['teachers'], :teacher_limit => "1" })
[@c1, @c2].each do |c|
expect(json.detect{|h| h['id'] == c.id}['teachers'].map{|t| t['id']}).to eq [@teacher.id]
end
end
describe 'sort' do
before :once do
@me = @user