Many to Many Relation with custom pivot table - php

I have 4 tables in project's database:
users (id, name)
teams (id, name)
team_members (id, user_id, team_id)
team_member_permissions (team_member_id, team_id)
I need to get user's teams. My current solution is to create teamMembers relationship in User model:
public function teamMembers()
{
return $this->hasMany(TeamMember::class);
}
members relationship in Team model:
public function members()
{
return $this->hasMany(TeamMember::class);
}
permissions relationship in TeamMember model:
public function permissions()
{
return $this->belongsToMany(Permission::class);
}
But how can I optimise it? For example, to get all teams for users I need to use
Team::whereHas('teamMember', function($query) use ($user){
$query->where('user_id', $user->id);
})->paginate();
But how can I implement a relationship that will contains all user's teams to get user's teams in one string of code, like $user->teams?

I suggest you use many to many relation in regards to your team_members tables to explicitly mention as pivot.
User model:
public function teams()
{
return $this->belongsToMany(Team::class, 'team_members');
}
Team model:
public function users()
{
return $this->belongsToMany(User::class, 'team_members');
}
Since you want to use whereHas clause on teamMember table, I believe that you want to extract teams based on the fact that all teams belonging to that user based on team_members table.
So, You can specify the table name on many to many relation as above.
Now you can use
$user->teams

Related

laravel 2 tables have 1:n relationship with the same table

I have a users table, a products table, and and an assets table. A user can have many assets, as can a product, meaning both Users, and Products have a 1:n relationship with assets. In Laravel how would show this relationship in Eloquent, is this a Polymorphic relationship, with the struct of the assets table columns being something like,
ID, type, file_path, ownable_id, ownable_type
I think your assets table columns should be
id, type, file_path, assetable_id, assetable_type
Add this relation to your user and product model
public function assets()
{
return $this->morphMany(Asset::class, 'assetable');
}
Next, add this relation to your asset model
public function assetable()
{
return $this->morphTo();
}
relation of user model
public function assets()
{
return $this->morphMany(Asset::class, 'assetable');
}
relation of asset model
public function assetable()
{
return $this->morphTo();
}

Laravel 5.4 Query DB with pivot table

So, I have the following Tables named:
ALBUMS(id, name, shared, group_id, user_id)
GROUPS(id, name, user_id)
GROUP_USER(group_id, user_id)
What I want to do is, using Laravel Eloquent to get the results of a query by checking if the AUTHENTICATED user is a member of the GROUP owned by the ALBUM.
Album Model:
public function groupSecurity()
{
return $this->belongsTo(Group::class, 'group_id');
}
Group Model:
public function ownedBy()
{
return $this->belongsTo(User::class, 'user_id');
}
public function members()
{
return $this->belongsToMany(User::class, 'group_user');
}
Thank you for your help :)
You can do like this:
$album = Album::whereHas('groupSecurity', function ($query) {
$query->whereHas('members', function($query2){
$query2->where('user_id', auth()->user()->id);
})->where('user_id', auth()->user()->id);
})->first();
So you search for one album that has a groupSecurity which has in his members the auth user and also it's owned by the auth user.
If a record match this conditions $album will have an instance of Album model, if not it will be null so you can do:
if($album){
// AUTHENTICATED user is a member of the GROUP owned by the ALBUM
}

Using JOIN inside relation

I have three tables: Tournaments, Participants, Users. The structure is:
Tournaments:
-Id
-Description
-Date
Participants
-Id
-Id_tourn
-Id_user
Users
-Id
-Name
On my blade template I need all the info from Tournaments table and info of the User which is the participant of that tournament.
I've created the relation between Tournaments and User Models.
UPDATE:
Tournaments Model:
public function users() {
return $this->belongsToMany('App\User', 'Participants', 'Id_tourn', 'Id_user');
}
public function getTournaments()
{
return $this->with('users')->get();
}
Tournament Controller:
public function show()
{
$tourns = new Tournaments();
$tournaments = $tourns->getTournaments();
return $tournaments;
}
but when I try $tournament->users in foreach loop it returns 0 results
Thanks a lot!
It seems you are using a One to Many relationship on a Many to Many case, here are the documentation of the Many to Many relationship. You need to make a relationship like this:
public function users() {
return $this->belongsToMany('App\User', 'Participants', 'Id_tourn', 'Id_user');
}
So you will can access users like this:
$tournament->users

querying based on the additional pivot table column in laravel

I have a User Model with the columns id, name, email and
a Course Model with the columns id, name, code and
a pivot table course_user.
Course and User has many-to-many relation
course_user table contains columns course_id, user_id, section
While taking courses, some users will be listed as 'Pending' in pivots section column and some users will be listed as 'A', 'B' etc in section column.
Question: I want to get those courses which are taken by at least one user and section is 'Pending'
So far, I've tried these:
In Course Model :
public function users(){
return $this->belongsToMany(User::class)
->withPivot('section');
->wherePivot('section', 'Pending');
}
Another Approach I've tried in course Model:
public function pendingUsers(){
return $this->belongsToMany(User::class)
->withPivot('section')
->wherePivot('section', 'like', 'Pending');
}
But all of these are giving me all of the courses.
Now, How can this job be done?
Define the relationship:
public function users()
{
return $this->belongsToMany(User::class)->withPivot('section');
}
Then:
Course::whereHas('users', function($q) {
$q->where('course_user.section', 'Pending');
})
->get();

Laravel Eloquent Relationship custom query

I have 2 tables: USERS and SUBJECTS
The relationship between USER and SUBJECT is many to many.
In the User.php and Subject.php models, I defined:
User.php
function subjects() { return $this->belongsToMany('App\User'); }
Subject.php
function users() { return $this->belongsToMany('App\Subject'); }
The pivot table is subject_user and it has 3 columns:
subject_id, user_id, finished
The finished value can only be between 0 and 1.
Now I know that when I want to select all the subjects that an user studied, I have to write $user->subjects.
But what if I want to select all the subjects that an user studied and the finished value in the pivot table is equal to 1?
You need to add "withPivot()" to your relationship definitions, like this:
function subjects() { return $this->belongsToMany('App\User')->withPivot('finished'); }
function users() { return $this->belongsToMany('App\Subject')->withPivot('finished'); }
Then you can do:
$user->subjects()->where('finished', 1)->get();
You will need to eager load that relationship and use the wherePivot method.
$user = User::with(['subjects' => function($q) {
$q->wherePivot('finished', 1);
}])->fine($user_id);

Categories