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();
Related
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
I have a model called unit that has this relationship
/**
* Get the users associated with the unit
*/
public function users()
{
return $this->hasMany('App\Models\User\UserData');
}
In the UserData model there is a column called user_id which I am trying to put in my condition in my query. I am trying to do a query like this
Unit::where('user_id', Auth::id())->first()
but there is no user_id column in the Unit table, only though the users relationship
Ended up doing this
Unit::whereHas('users', function($q) {
$q->where('user_id', Auth::id());
})->first();
I have two tables, users and projects and another table called users_project used to perform many to many relation.
Users columns: id, firstname, lastname, ... (others not important for this post)
Projects columns: id, commercial, name, ... (others not important for this post)
Users_project: user_id, project_id
In my User model class I have two methods:
public function commercial_projects() {
return $this->hasMany('App\Project', 'commercial', 'id');
}
and
public function assigned_projects() {
return $this->belongsToMany(
'App\Project',
'users_project',
'user_id',
'project_id'
);
}
This methods works fine.
The first return how many projects have the user involved as commercial user
The second return how many projects are assigned to user
I want to have another method that return all project where user are involved in (commercial or assigned)
I wrote this method as follow:
public function projects() {
return $this -> assigned_projects() -> union( $this->commercial_projects() );
}
But I have the error caused by pivot column added by belongsToMany relationship:
"SQLSTATE[21000]: Cardinality violation: 1222 The used SELECT statements have a different number of columns (SQL: (select `projects`.*, `users_project`.`user_id` as `pivot_user_id`, `users_project`.`project_id` as `pivot_project_id` from `projects` inner join `users_project` on `projects`.`id` = `users_project`.`project_id` where `users_project`.`user_id` = 13) union (select * from `projects` where `projects`.`commercial` = 13 and `projects`.`commercial` is not null))"
How can I remove pivot column from database request or find a way to fix this issue?
Tnx a lot
I think you need to select only projects columns of assigned_projects
->select("projects.*")
To be like this
return $this->assigned_projects()->select("projects.*")->union($this->commercial_projects());
I want to use where clause on the another relationship not my current selecting model as below table
table Customer
-------id-----customer_name
Table ModelA
table Customer
-------id-----fk_custome_id
table ModelB
-------id-----fk_ModelA_id
Function in Controller
$data['data'] = customer::with(['modelA','modelA.modelB'])
->where('fk_customer_id', 2)->get();
Customer Model
final function ModalA (){
return $this->hasMany('App\Models\ModelA', 'fk_customer_id', 'id');
}
ModelA Model
final function Modelb (){
return $this->hasMany('App\Models\ModelB', 'fk_modelA_id', 'id');
}
Error:
I will got error as below because select sql don't find the column name fk_customer_id in table customer, So how can I user fk_customer_id (in table ModelA) for where.
You can useYou can use whereHas like:
$data['data'] = customer::with(['modelA','modelA.modelB'])
->whereHas('modelA', function ($query) {
$query->where('fk_customer_id', 2);
})->get();
It's because when you're using with you just eager load constrints but you won't attach it to the main query (of the customer model). So there are two way: one modern with using whereHas or using join queries.
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);