skip to Main Content

I try to add Model Relation on Laravel. I know how we can make this but I don’t understand, I can link all Model I need.

So this is my problem :

I build a exam system and it’s work like this :

Evaluation -> Examid -> QuestionCategory -> Question -> Response.

So in Evaluation session, We choose a Examen which has question categories, which has questions, which has response.

So I wrote this :

public function testtheorique($session){
    $eval = Evaluation::find($session);
    $caces = $eval->caces_cat;
    $theorique = $eval->theorique;
    $questioncat = $theorique->examcategory;
    $question = $questioncat->categoryQuestions;
}

And this is my Models :

//Evaluation Model
public function theorique(){
        return $this->belongsTo(TestTheorique::class);
    }


//TestThorique Model
public function examcategory(){
        return $this->hasMany(QuestionCategorie::class, 'exam_id');
    }


//QuestionCategory Model
public function categoryQuestions(){
        return $this->hasMany(Question::class, 'category_id', 'id');
    }


//Question Model
 public function qcategory(){
        return $this->belongsTo(QuestionCategorie::class);
    }

So when I make this dd($eval) I have all the data displayed with the relationships but only up to the examcategory. I can’t display the Question because I don’t have relation.

So I don’t know how I can have the question relation. I can’t see where I made an error.

Thanks for your help.

3

Answers


  1. Chosen as BEST ANSWER

    So for more precision, here is exactly what I want via screens.

    So this is my complete function :

    public function testtheorique($session){
            $eval = Evaluation::find($session);
            $caces = $eval->caces_cat;
            $theorique = $eval->theorique;
            $questioncat = $theorique->examcategory;
    
            $categories = QuestionCategorie::with(['categoryQuestions' => function ($query) {
                $query->inRandomOrder()
                    ->with(['reponse' => function ($query) {
                        $query->inRandomOrder();
                    }]);
            }])
            ->whereHas('categoryQuestions')
            ->get();
    
        return view('session.theorique', compact('categories', 'caces'))
        ->with('eval', $eval);
        }
    

    So when I make a dd($eval) I have this :

    Evaluation Model with relation

    Relation with TestTheorique

    Then Relation with QuestionCategorie

    Details of QuestionCategorie without the relation with Question

    But I wrote this to try $categories and I have my Questions with the QuestionCategory and Response relation. This is the screenshot from dd($categories)

    Screen of dd($categories)

    Detail of QuestionCategorie

    Detail of Relation from QuestionCategorie

    Detail Question with Response relation

    But it's not good because I have all the questions that appear from the database and not the ones that are part of the TestTheorique session.

    So I want have one Session of Evaluation. This session have one TestTheorique (Examid), Then, this test with several QuestioCategorie, which has several Question with Response.


  2. For using only laravel/laravel package it only enables you to access only 3 table with hasOneThrough or hasManyThrough relations.

    To achieve what you want or what atleast i think you’re asking can be done with help of staudenmeir/eloquent-has-many-deep packages.

    For Laravel 8:
    composer require staudenmeir/eloquent-has-many-deep:"^1.13"

    For Laravel 9:
    composer require staudenmeir/eloquent-has-many-deep:"^1.7"

    Then,

    In Your model :

    use StaudenmeirEloquentHasManyDeepHasRelationships;
    

    and include in your Model class by:

    use HasRelationships;
    

    Then in your model method do hasOneDeep or hasManyDeep according to usage:

    return $this->hasOneDeep('Model_Name_You_Want_To_Access_Through', ['Model_Access_Via1', 'Model_Access_Via2'], ['ForeignKeyOf_Model_Access_Via1', 'ForeignKeyOf_Model_Access_Via2', 'ForeignKeyOf_Model_Name_You_Want_To_Access_Through']);
    

    This can keep going on but remember you have to provide through array according to structure.

    For references:

    https://github.com/staudenmeir/eloquent-has-many-deep

    Option 2:

    In your ExamId Model:
    You will need to create some relations to access questions, From ExamId model so we will use QuestionCategory Models and access everything through it.

    ExamId may have multiple QuestionCategory (hasMany)

    and QuestionCategory will have multiple questions (hasMany)

    so in your ExamId Model:

    public function getQCategory()
    {
        return $this->hasMany('AppModelsQuestionCategory')->with('getQuestion');
    }
    

    In your Question Category Model:

     public function getQuestion()
     {
         return $this->hasMany('AppModelsQuestion');
     }
    

    In your controller:

     $exam = ExamId::with('getQCategory')->find($id);
    

    now $exam will contain ExamId, Categories and Questions.

    Login or Signup to reply.
  3. Ok it’s solved !
    So this is what I maked.

    In my TestTheorique Model, I changed this line like this :

    public function examcategory(){
        return $this->hasMany(QuestionCategorie::class, 'exam_id')->with('getQuestion');
    }
    

    to make the relation with QuestionCategorie and select the getQuestion function. In my QuestionCategorie Model I add this :

     public function getQuestion(){
        return $this->hasMany(Question::class, 'category_id', 'id')->with('reponse');
    }
    

    }

    to make the relation with Question and select the reponse function. In my Question Model I add this :

    public function reponse()
    {
        return $this->hasMany(QuestionReponse::class, 'question_id', 'id');
    }
    

    And now it works. If I did a dd($eval) I have all the session data displayed and not all the questions recorded in the database.

    I really want to thank Sumit Kumar for his help, he gave me part of the answer.

    Now I continue my dev.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search