If I understand you correctly then your models are set up like so:
Program hasMany Module hasMany QuizContent hasMany QuizQuestion
or more simply:
Program hasMany Module hasMany Quiz hasMany Question
There can be quite a lot to think about in these applications, so it is hard to tell you how we might structure this without knowing the answer to more questions:
- Can users do a quiz more than once?
- Can users return to questions they have already answered?
- Are the answers saved individually?
- Do the results get saved up and then stored at the end?
- Do the results get stored in the database?
- Are the results simply emailed off somewhere?
Assuming you want to strictly control the question seen, not allowing users to go back using their browser controls, holding the state (incomplete quizzes) in sessions instead of the database, you might approach it like this:
class QuizController extends AppController {
# allow user to do a quiz
function do($id) {
# do something with each answer submitted
if ($this->data) {
// validate, save to database, or store in session until the end
$questionNumber = $this->Session->read('Quiz.question');
$this->Session->write('Quiz.question', $questionNumber + 1);
$this->redirect(array('action' => 'do', $id));
}
# get the quiz (and questions)
$quiz = $this->Quiz->find('first', array(
'conditions' => array('Quiz.id' => $id),
'contain' => array('Question'), // if using Containable
));
# quiz doesn't exist
if (!$quiz) {
$this->cakeError('error404');
}
# get the question number
$questionNumber = $this->Session->read('Quiz.question');
# quiz hasn't been started
if (!$questionNumber) {
$questionNumber = 1;
$this->Session->write('Quiz.question', $questionNumber);
}
# get the question
$question = Set::extract("/Question[$questionNumber]", $quiz);
# there are no more questions
if (!$question) {
// finalize quiz, save to database, redirect to obvious place
$this->Session->setFlash('Quiz complete');
$this->redirect(array('action' => 'index', $quiz['Quiz']['id']));
}
# set variables to the view
$this->set(compact('quiz', 'question'));
}
}
Note: In the example above I renamed the models to Quiz and Question to improve readabilty.