Reputation: 592
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
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
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
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