Only include quiz question_types in api responses

The Quiz#question_types method is expensive for large quizzes. It's
currently called every time a quiz is serialized, even though we only
need the question_types attribute in API responses (I believe it's used
by the mobile app).

This commit moves the question_types attribute to a separate
QuizApiSerializer that is only used in API responses.

Fixes QO-356
Fixes QO-357

Test plan:

- Create several huge quizzes (tens of thousands of questions across
  multiple question groups)
- Open the quizzes list page
- Check that the page loads reasonably quickly

Change-Id: Id18a32fc47f20cd24cb178e972f49e8984bfe53e
Reviewed-on: https://gerrit.instructure.com/149829
Reviewed-by: James Williams  <jamesw@instructure.com>
Tested-by: Jenkins
QA-Review: David Tan <dtan@instructure.com>
Product-Review: Omar Khan <okhan@instructure.com>
This commit is contained in:
Omar Khan 2018-05-10 11:01:08 -05:00
parent 5252a6087e
commit 96e7f9187e
6 changed files with 60 additions and 5 deletions

View File

@ -0,0 +1,26 @@
#
# Copyright (C) 2018 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
module Quizzes
class QuizApiSerializer < QuizSerializer
# The Quiz#question_types method is expensive to call for large quizzes.
# Splitting it out into a separate serializer allows us to include it only
# where needed (the API).
attributes :question_types
end
end

View File

@ -39,7 +39,7 @@ module Quizzes
:quiz_submissions_zip_url, :preview_url, :quiz_submission_versions_html_url,
:assignment_id, :one_time_results, :only_visible_to_overrides,
:assignment_group_id, :show_correct_answers_last_attempt, :version_number,
:question_types, :has_access_code, :post_to_sis, :anonymous_submissions
:has_access_code, :post_to_sis, :anonymous_submissions
def_delegators :@controller,
# :api_v1_course_assignment_group_url,

View File

@ -71,7 +71,7 @@ module Api::V1::Quiz
scope: user,
session: session,
root: :quizzes,
each_serializer: Quizzes::QuizSerializer,
each_serializer: Quizzes::QuizApiSerializer,
controller: self,
serializer_options: options).as_json
else

View File

@ -234,7 +234,7 @@ describe Quizzes::QuizzesApiController, type: :request do
'Accept' => 'application/vnd.api+json')
@json = @json.fetch('quizzes').map { |q| q.with_indifferent_access }
expect(@json).to match_array [
Quizzes::QuizSerializer.new(@quiz, scope: @user, controller: controller, session: session).
Quizzes::QuizApiSerializer.new(@quiz, scope: @user, controller: controller, session: session).
as_json[:quiz].with_indifferent_access
]
end
@ -272,7 +272,7 @@ describe Quizzes::QuizzesApiController, type: :request do
@course.reload
@quiz = @course.quizzes.first
expect(@json).to match_array [
Quizzes::QuizSerializer.new(@quiz, scope: @user, controller: controller, session: session).
Quizzes::QuizApiSerializer.new(@quiz, scope: @user, controller: controller, session: session).
as_json[:quiz].with_indifferent_access
]
end

View File

@ -0,0 +1,25 @@
#
# Copyright (C) 2018 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
require 'spec_helper'
describe Quizzes::QuizApiSerializer do
it 'includes question_types' do
expect(described_class._attributes).to include(:question_types)
end
end

View File

@ -60,7 +60,7 @@ describe Quizzes::QuizSerializer do
:allowed_attempts, :one_question_at_a_time, :question_count,
:points_possible, :cant_go_back, :access_code, :ip_filter, :due_at,
:lock_at, :unlock_at, :published, :show_correct_answers_at,
:hide_correct_answers_at, :show_correct_answers_last_attempt, :question_types,
:hide_correct_answers_at, :show_correct_answers_last_attempt,
:has_access_code
].each do |attribute|
@ -625,4 +625,8 @@ describe Quizzes::QuizSerializer do
new_json = quiz_serializer.as_json[:quiz]
expect(new_json[:anonymous_submissions]).to eq true
end
it "does not include question_types" do
expect(json.keys).not_to include(:question_types)
end
end