kjanko
kjanko

Reputation: 592

Eloquent triple relation

I'm having a hard time understanding on how to model a triple relation in Laravel.

I have 3 models: User, Tour and Photo

Each tour has users associated with it and all users can post photos. Which means the database looks something like this:

id , tour_id, user_id, photo_id

This way I know which user posted which photo for which tour. My question is, how do I model this in Eloquent?

Upvotes: 1

Views: 1342

Answers (3)

Geordy James
Geordy James

Reputation: 2408

Update Based on your last comment.

The simplest answer to your question is by using relations belongsToMany and hasMany.

Let me explain. You need 4 table users, tours, tour_user and photos.

users table contain id,name

tours table contain id,name,

tour_user table contain id,tour_id,user_id

photos table contain id,name,user_id,tour_id

Why belongsToMany ? because each user has more than one tour and each tour has more than one users. So we link both tables by using a third table tour_user. It also helps in normalization.

Now that we have examined the table structure for the relationship, let's define it on the User model:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{

    public function tours()
    {
        return $this->belongsToMany('App\Tour');
    }
    /* To retrieve photos of a user */
    public function photos()
    {
        return $this->hasMany('App\Photo');
    }

}

Tour model:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Tour extends Model
{

    public function users()
    {
        return $this->belongsToMany('App\User');
    }
    /* To retrieve photos of a tour*/
    public function photos()
    {
        return $this->hasMany('App\Photo');
    }

}

Now Photo model:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Photo extends Model
{

    public function users()
    {
        return $this->belongsTo('App\User');
    }
    public function tours()
    {
        return $this->belongsTo('App\Tour');
    }

}

Now let find all tour of a specific user by using

public function show($id)
{
    $user = User::find($id);
    return view('show')->withUser($user) ;
}

Now in show view, page lets extract all tours of that user and his photos

@foreach($user->tours as $tour)
     {{ $tour->name }}
     @foreach($tour->photos as $photo)
         @if($user->id == $photo->user_id)
         {{ $photo->name }}
         @endif
     @endforeach
@endforeach

Upvotes: 2

Sapnesh Naik
Sapnesh Naik

Reputation: 11656

First make sure you have a user_id foriegn key field in your tour model and 'photo_id' foriegn key field in your user moel

the trick is to have user model with a hasOne/hasMany relationship with photo model and then have tour model with a hasOne/hasMany relationship with the user model.

1 - first in your user model define a relationship like this

public function photo()
{
    return $this->hasOne('App\Photo');
}

2 - In your tour model define a hasMany relationship like this

public function users()
{
    return $this->hasMany('App\User');
}

so when you fetch a tour model like

$a = tour::All(); you can do $a->users->'field_in_user_table' or $a->users->photo; // to get the photo field value from photo table

Upvotes: 0

Onix
Onix

Reputation: 2179

You should have: one to many Tour > user and one to many User > Photo

include this function in your Tour model.

public function allusers()
    {
        return $this->hasMany(User::class);
    }

and this in your User model.

public function allphotos()
    {
        return $this->hasMany(Photos::class);
    }

Then you can get a tour $tour = Tour::find(1);

and just use the function to get the users with this:

$usersOnTour = $tour->allusers();

Upvotes: 0

Related Questions