[drupal-devel] Request for input on Quiz module data structure [long]

Angie Byron drupal-devel at webchick.net
Thu Oct 13 17:38:19 UTC 2005

Thanks a lot for your reply, Robert!

I should clarify that my goal is not necessarily complete and total 
normalization of the schema (as that would require at least 1 additional 
database table for each question type, which would quickly become cumbersome and 
create dependencies), but to strike a balance between intense processing/RAM 
usage being required for "easy" queries that everyone is going to want to make 
(what was the user's average score on these quizzes?) but at the same time 
allowing the quiz module to retain the "polymorphism" which is the real strength 
of the current system.

 > Now that I'm looking at the ER diagram of the SOLUTION, I think you're ok for 
the time being, as long as all of the logic for querying the 
quiz_question_answer and quiz_question_results tables are delegated to the 
question types.

Yep, that is the plan.

When I want to display a question to the screen, I call its "render_question" 
hook from quiz.module, like:

module_invoke($question->type, 'render_question', $question->nid);

In your example of an audio-type question, if the question was, "The cow 
goes..?", the quiz_question_answer.answer field would probably contain something 
like "files/sounds/moo.mp3" Inside the audio_question.module, in its 
render_question hook, it would know to take the data extracted from the answer 
field, translate it into an HTML statement to display a link to the file (or 
embed it in a Flash player or whatever), and display that to the screen rather 
than simply displaying the file paths and making little radio buttons/checkboxes 
with answers next to them like multichoice does.

Similarly, each question type keeps track of its own way of determining whether 
a submitted answer is correct or not. This is done in the evaluate_question hook 
which is called from quiz.module, like:

module_invoke($question->type, 'evaluate_question', $question->nid);

This will do all the question type's internal logic of parsing the answer field 
to determine if it is correct, and return the amount of points a user earned on 
that question (currently, this is either 0 or 1, but by adding the 'points' 
field I should be able to make weighted questions, which has been a common request).

So these two hooks together should handle querying quiz_question_answer (as well 
as storing in quiz_question_results in the expected format). I will maybe need 
to add a third hook to handle displaying result information to the screen 
(render_result?) so that quiz.module remains blissfully unaware of how each 
question handles this.

 > If you're going to store a list of answer ids in a column, however, use
 > serialize(). It's not that serialize is evil; it is definitely better than
 > making your own string parsing routines where you have to remember whether to
 > split on comma or pipe, and worry about whether someone might use the pipe in
 > the answer.

Ah, that totally makes sense!! That would be a much better way to handle the 
"properties" field, as well as the answer field on those questions that could 
conceivably have more than one correct answer (for example, for fill in the 
blank questions you might want to catch "saint paul" as well as "st. paul" as 
well as "st paul").

Remind me next time I am struggling with something for a long time to just post 
here and get some help. :P You guys are awesome, thank you.


More information about the drupal-devel mailing list