Search code examples
phplaravelmodelcontroller

How many Model relation we can have in Laravel?


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.


Solution

  • 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 \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.