How to save nested data in Laravel using Eloquent (without iterating too much)

Viewed 150

Assume having the following database structure:

enter image description here

So, basically, there are courses, each one has sections, each section has lessons and each lesson may be an article or a quiz. If it is a quiz it consists of questions and each question has multiple answers.

The result that we receive from the front-end is a nested object with all the information inside. Like this:

[
   {
      "id":1,
      "title":"HTML Basics",
      "lessons":[
         {
            "id":993810,
            "title":"Lorem Ipsum",
            "content":{
               "text":"Hello world. Some long content describing HTML."
            },
            "type":"article"
         }
      ]
   },
   {
      "id":2,
      "title":"HTML Advanced",
      "lessons":[
         {
            "id":844341,
            "title":"The Quizzz",
            "content":{
               "questions":[
                  {
                     "id":968703,
                     "text":"First man on the moon was:",
                     "answers":[
                        {
                           "id":36540,
                           "text":"Neil Armstrong",
                           "correct":true
                        },
                        {
                           "id":752795,
                           "text":"Jurij Gagarin",
                           "correct":false
                        },
                        {
                           "id":150651,
                           "text":"Donald Trump",
                           "correct":false
                        }
                     ]
                  },
                  {
                     "id":224986,
                     "text":"HTML is shortcut for:",
                     "answers":[
                        {
                           "id":502645,
                           "text":"Hypster Travel Moon Landing",
                           "correct":false
                        },
                        {
                           "id":650453,
                           "text":"How to money loss",
                           "correct":false
                        },
                        {
                           "id":468116,
                           "text":"Hyper text markup language",
                           "correct":true
                        },
                        {
                           "id":503678,
                           "text":"Hidro termal moon liquids",
                           "correct":false
                        }
                     ]
                  }
               ]
            },
            "type":"quiz"
         }
      ]
   }
]

THE QUESTION: What would be the best approach to iterate through the object and save everything accordingly using Eloquent models. Currently I am doing it with 4 nested foreach loops and I can not think of a smoother and smarter solution.


CURRENT CODE

$sections = json_decode(request()->input('sections'));

foreach($sections as $section) {
    //create and save a section
    $sectionObject = new Section();
    $sectionObject->title = $section->title;
    $course->sections()->save($sectionObject);

    //iterate through each section's lessons
    foreach($section->lessons as $lesson) {
        //create a lesson
        $lessonObject = new Lesson();
        $lessonObject->title = $lesson->title;
        $lessonObject->type = $lesson->type;
                
        if($lessonObject->isArticle()) {
            //if it is an article, create an Article object and associate it with the given lesson
            $articleObject = new Article();
            $articleObject->content = $lesson->content->text;
            $articleObject->save();
            $lessonObject->lessonable()->associate($articleObject);
        } else if($lessonObject->isQuiz()) {
            //if it is a quiz, create a Quiz object and associate it with the given lesson
            $quizObject = new Quiz();
            $quizObject->save();
            $lessonObject->lessonable()->associate($quizObject);
            //then proceed to create the quiz's questons and answers
            foreach($lesson->content->questions as $question) {
                $quizQuestion = new QuizQuestion();
                $quizQuestion->text = $question->text;
                $quizObject->questions()->save($quizQuestion);

                //and for each questions insert the answers into database
                foreach($question->answers as $answer) {
                    $quizQuestionAnswer = new QuizQuestionAnswer();
                    $quizQuestionAnswer->text = $answer->text;
                    $quizQuestionAnswer->correct = $answer->correct;
                    $quizQuestion->answers()->save($quizQuestionAnswer);
                }
            }
        }
        //finally save the lesson correlating it with the given section
        $sectionObject->lessons()->save($lessonObject);
    }
}
0 Answers
Related