skip to Main Content

I have a schools table, I also have a school_relations table. The issue is i want to only show once relation between schools and not have to repeat it the other way round on the table of the relations.

Here is the migration

Schema::create('school_relations', function (Blueprint $table) {
    $table->id();
    $table->unsignedBigInteger('school_id');
    $table->foreign('school_id')->references('id')->on('schools');
    $table->unsignedBigInteger('related_school_id');
    $table->foreign('related_school_id')->references('id')->on('schools');
    $table->timestamps();
});

Example in database:

id school_id related_school_id
1 15 16
2 15 17
3 16 17

So, the school with id 15 is related to school with id 16, then the school with id 15 related to 17 and the last row the school with id 16 is related to 17.

As observed all the three are related to each other, but as of now i can only do this

$initialSchool  = AppModelsSchool::find(15);
$relatedSchoolsInitial = $initialSchool->relatedSchools;

Which only works with showing 15 is related to 16 and 17 but when am in 17 or 16 i cant get to see that its related to 15 and the other one

What can i do so that i can querry such a relation with only 3 entries to show relation between 15,16 and 17

2

Answers


  1. To achieve the desired behavior of showing the relations between schools without duplicating entries in the school_relations table, you can modify your query to consider both columns when searching for relations in a many-to-many relationship.

    Here’s a suggestion on how you can modify your Laravel query to achieve this:

    // Query to find relations between schools 15, 16, and 17
    $relatedSchools = AppModelsSchoolRelation::whereIn('school_id', [15, 16, 17])
        ->whereIn('related_school_id', [15, 16, 17])
        ->get();
    
    // Output the related schools
    foreach ($relatedSchools as $relation) {
        echo "School with ID " . $relation->school_id . " is related to School with ID " . $relation->related_school_id . "n";
    }
    

    By using the whereIn method for both ‘school_id’ and ‘related_school_id’, you can query the school_relations table to find the relations between schools 15, 16, and 17 without duplicating entries.

    This approach allows you to search from both columns and retrieve the desired relations between the schools without redundancy.

    Login or Signup to reply.
  2. Your School model can have the following two relations:

    
    public function relatedTo()
    {
        return $this->belongsToMany(
            School::class, 'school_relations', 'school_id', 'related_school_id'
        );
    }
    
    public function relatedBy()
    {
        return $this->belongsToMany(
            School::class, 'school_relations', 'related_school_id', 'school_id'
        );
    }
    

    You need a way to have a function called for example related() and this function can union those two relationships:

    public function relatedSchools()
    {
        $relatedTo = $this->relatedTo()->select(
            'schools.*',
            'school_relations.school_id as pivot_school_id',
            'school_relations.related_school_id as pivot_related_school_id');
        $relatedBy = $this->relatedBy()->select(
            'schools.*',
            'school_relations.school_id as pivot_school_id',
            'school_relations.related_school_id as pivot_related_school_id'
        );
    
        return $relatedTo->union($relatedBy);
    }
    

    In this case you can call:

    $initialSchool = AppModelsSchool::find(15);
    $relatedSchoolsInitial = $initialSchool->relatedSchools;
    

    And get all relations with other schools of school 15 where the id 15 is in either school_id or related_school_id in school_relations table.

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