Home > OS >  How many Model relation we can have in Laravel?
How many Model relation we can have in Laravel?

Time:10-25

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.

CodePudding user response:

For using only laravel/laravel package it only enables you to access only 2 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 \Staudenmeir\EloquentHasManyDeep\HasRelationships;

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('App\Models\QuestionCategory')->with('getQuestion');
}

In your Question Category Model:

 public function getQuestion()
 {
     return $this->hasMany('App\Models\Question');
 }

In your controller:

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

now $exam will contain ExamId, Categories and Questions.

CodePudding user response:

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

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.

  • Related