Create Many2many relationship with pivot table
1. Create Factory with the specific model
Using this query we can create factory class for specific model.
php artisan make:factory ProjectFactory --model=Project
2. Create Seeder class
Using this query we can create seeder class.
php artisan make:seeder ProjectSeeder
Write below code in this class in a run method in ProjectSeeder class
public function run()
{
factory(Project::class,10)->create();
foreach (Project::all() as $key => $project) {
$users = User::inRandomOrder()->take(rand(1,3))->pluck('id');
$project->users()->attach($users);
}
}
3. Create a relationship to the User model using Project Model.
Inside Project Model
public function users(){
return $this->belongsToMany(User::class)
//->withTimestamps()
//->withPivot(['is_manager'])
//->as('project_user');
/*
if pivot table name is differet than set the relation like so,
return $this->belongsToMany(User::class,'projects_users','projects_id',
'users_id');
Note: By default systtem automatically read/look for project_user (Not
user_project).
foriegn id's naming convension will be like so project_id and user_id.
change the name of pivot
->as('project_user');
*/
}
4. Run Seeder (specific seeder)
php artisan db:seed --class=ProjectSeeder
After that project will attach/assign to the users.
Set manager field with 1 and 0 values, working on projects in pivot table
Add another field is_manager in pivot table with a default value of 0. Change the seeder class code to below.
factory(Project::class,10)->create();
foreach (Project::all() as $key => $project) {
$users = User::inRandomOrder()->take(rand(1,3))->pluck('id');
foreach ($users as $key => $user) {
$project->users()->attach($users,['is_manager'=>rand(0,1)]);
}
}
Create the relationship in the Project table.
public function users(){
return $this->belongsToMany(User::class)
//->withTimestamps()
->withPivot(['is_manager'])
//->as('project_user');
/*
if pivot table name is differet than set the relation like so,
return $this->belongsToMany(User::class,'projects_users','projects_id',
'users_id');
Note: By default systtem automatically read/look for project_user (Not
user_project).
foriegn id's naming convension will be like so project_id and user_id.
change the name of pivot
->as('project_user');
*/
}
Rename pivot while showing data
Go to the project model or where the relationship is defined. Add this line.
Next we need to specify a particular relationship with the manager only.
For example, I want to fetch/check managers working on the projects
define relation like so
public function managers(){
return $this->belongsToMany(User::class)
->withTimestamps()
->withPivot(['is_manager'])
->wherePivot('is_manager',1)
->as('project_manager');
}
Show data in the view
<h3>Manager working on projects</h3>
<table>
<thead>
<tr>
<th>Project</th>
<th>Users</th>
</tr>
<tbody>
@foreach($projects as $project)
<tr>
<td>{{$project->name}}</td>
<td>
<ul>
@foreach($project->managers as $manager)
<li>
{{$manager->name}}
----[{{$manager->project_manager->created_at}}]----
</li>
@endforeach
</ul>
</td>
</tr>
@endforeach
</tbody>
</thead>
</table>
Complete code of Project Model
namespace App;
use Illuminate\Database\Eloquent\Model;
class Project extends Model
{
protected $fillable = ['name'];
public function users(){
return $this->belongsToMany(User::class)
->withTimestamps()
->withPivot(['is_manager'])
->as('project_user');
/*
if pivot table name is differet than set the relation like so,
return $this->belongsToMany(User::class,'projects_users','projects_id',
'users_id');
Note: By default systtem automatically read/look for
project_user (Not user_project).
foriegn id's naming convension will be like so project_id and user_id.
change the name of pivot
->as('project_user');
*/
}
public function managers(){
return $this->belongsToMany(User::class)
->withTimestamps()
->withPivot(['is_manager'])
->wherePivot('is_manager',1)
->as('project_manager');
/*
if we have another field priority mean periority of manager/project
then get data with priority wise like so
wherePivotIn('priority',[1,2])
*/
}
}
Create a relation with the Pivot Model class
<?php
namespace App;
use Illuminate\Database\Eloquent\Relations\Pivot;
class ProjectUser extends Pivot
{
//
}
Inside the migration CreateProjectUserTable class write code with define manager_id as foreign key
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateProjectUserTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('project_user', function (Blueprint $table) {
$table->unsignedBigInteger('project_id')->constrained();
$table->unsignedBigInteger('user_id')->constrained();
// add timestamp when project assign to user
$table->timestamps();
// define manager of the project
// $table->boolean('is_manager')->default(false);
$table->foreignId('manager_id')->references('id')->on('users');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('project_user');
}
}
Create Relation using the Pivot Model.
<?php
namespace App;
use Illuminate\Database\Eloquent\Relations\Pivot;
class ProjectUser extends Pivot
{
public function manager(){
return $this->belongsTo(User::class,'manager_id');
}
}
Now in the seeder class write the below code.
<?php
use Illuminate\Database\Seeder;
use App\Project;
use App\User;
// use Illuminate\Database\Eloquent\Factories\Factory;
class ProjectSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
// factory(Project::class,10)->create();
foreach (Project::all() as $key => $project) {
$users = User::inRandomOrder()->take(rand(1,3))->pluck('id');
foreach ($users as $key => $user) {
// $project->users()->attach($users,['is_manager'=>rand(0,1)]);
$project->users()
->attach($users,['manager_id'=>User::inRandomOrder()->first()->id]);
}
}
}
}
OR
<?php
$project->users()->attach($users,['is_manager'=>rand(0,1),
'manager_id'=>User::inRandomOrder()->first()->id]);
Now specify in Project Model that we have manager_id
<?php
public function myusers(){
return $this->belongsToMany(User::class)
->withTimestamps()
->withPivot(['manager_id'])
->using(ProjectUser::class);
}
Now in view display data like.
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<h3>Manager working on projects</h3>
Relation: project has users and user calling the pivot model and
pivot model calling the manager relation and this relation calling the name.
<table>
<thead>
<tr>
<th>Project</th>
<th>Users</th>
</tr>
<tbody>
@foreach($projects as $project)
<tr>
<td>{{$project->name}}</td>
<td>
<ul>
@foreach($project->myusers as $user)
<li>
{{$user->name}}
----[{{$user->pivot->created_at}}]
----[{{$user->pivot->manager->name}}]
</li>
@endforeach
</ul>
</td>
</tr>
@endforeach
</tbody>
</thead>
</table>
</body>
</html>
Comments
Post a Comment