Laravel Eloquent Relationship with 4 tables (3 model + 1 table) - laravel

Hi I have this 4 tables
Employee:
EmployeeID,
EmployeeName,
EmployeeEmail,
EmployeePassword
Department:
DepartmentID,
DepartmentName
Position:
PositionID,
PositionType
employee_deployment:
EmployeeDeploymentID,
EmployeeID,
DepartmentID,
PositionID
I created a migration for a Pivot table employee_deployment
public function up()
{
// Set schema to create field of table
Schema::create('employee_deployment', function (Blueprint $table) {
$table->bigIncrements('EmployeeDeploymentID');
$table->bigInteger('EmployeeID')->unsigned();
$table->bigInteger('DepartmentID')->unsigned();
$table->bigInteger('PositionID')->unsigned();
});
Schema::table('employee_deployment', function ($table) {
$table->foreign('EmployeeID')->references('EmployeeID')->on('tbl_employees')->onDelete('cascade');
$table->foreign('DepartmentID')->references('DepartmentID')->on('tbl_departments')->onDelete('cascade');
$table->foreign('PositionID')->references('PositionID')->on('positions')->onDelete('cascade');
});
}
Can someone help me to create a relationship for each model? And save the data into pivot table (employee_deployment table).

A pivot table cannot be used in this way to define 2 relationships at once, instead I would recommend having a Deployment model which has a one to one relationship with the other three models.
class Deployment extends Model
{
public function employee()
{
return $this->hasOne('App\Employee');
}
public function department()
{
return $this->hasOne('App\Department');
}
public function position()
{
return $this->hasOne('App\Position');
}
}
class Employee extends Model
{
public function deployment()
{
return $this->belongsTo('App\Deployment');
}
}
class Position extends Model
{
public function deployment()
{
return $this->belongsTo('App\Deployment');
}
}
class Department extends Model
{
public function deployment()
{
return $this->belongsTo('App\Deployment');
}
}
If you want to be able to access the relationships between Employee and Position or Position and Department or Employee and Department directly you can also add hasOneThrough relationships to the other 3 models
public function employee()
{
return $this->hasOneThrough('App\Employee', 'App\Deployment');
}
public function department()
{
return $this->hasOneThrough('App\Department', 'App\Deployment');
}
public function position()
{
return $this->hasOneThrough('App\Position', 'App\Deployment');
}
I think this should get you the relationships you're looking for
If any of these relationships aren't 1 to 1 then you'll need pivot tables between Deployment and the other 3 models but you should be able to just switch hasOneThrough to hasManyThrough to keep the direct relationships
For your migrations, if you don't use regular id columns on the employee, department, and position models you'll have to add a custom foreign key definition to the relationships. As an example the one for Deployment->Employee would be
public function employee()
{
return $this->hasOne('App\Employee', 'EmployeeID', 'EmployeeID');
}

Related

Laravel 8.x, 3 models and many to many relationship

I am new to laravel and trying the following:
I have these tables:
disciplines: id | name
specialties: id | name
categories: id | name
discipline_specialty (pivot table): id | discipline_id | specialties_id
Discipline model:
public function specialties()
{
return $this->belongsToMany(Specialty::class);
}
Specialty model:
public function disciplines()
{
return $this->belongsToMany(Discipline::class);
}
My question is:
how can I relate (many to many) the categories to the pivot table discipline_specialty in order to access the category name with the discipline and specialty ids?
I had thought of an additional pivot table that linked category id and discipline_specialty id but I don't know if it's the best solution and how to do it. Do you have any suggestions? Any help is appreciated.
You can introduce a junction/pivot model that will relate these 3 relations as many-to-one/belongsTo and one-to-many/hasMany from Discipline/Speciality/Category.
Discipline Speciality Category
\\ || //
\\ || //
DisciplineSpecialityCategory
This DisciplineSpecialityCategory model will have following attributes or FKs
Table: discipline_speciality_category
discipline_id
speciality_id
category_id
Now you model definitions will be like
class Discipline extends Model
{
public function disciplineSpecialityCategory()
{
return $this->hasMany(DisciplineSpecialityCategory::class, 'id', 'discipline_id');
}
}
class Speciality extends Model
{
public function disciplineSpecialityCategory()
{
return $this->hasMany(DisciplineSpecialityCategory::class, 'id', 'speciality_id');
}
}
class Category extends Model
{
public function disciplineSpecialityCategory()
{
return $this->hasMany(DisciplineSpecialityCategory::class, 'id', 'category_id');
}
}
class DisciplineSpecialityCategory extends Model
{
public function discipline()
{
return $this->belongsTo(Discipline::class, 'id', 'discipline_id');
}
public function speciality()
{
return $this->belongsTo(Speciality::class, 'id', 'speciality_id');
}
public function category()
{
return $this->belongsTo(Category::class, 'id', 'category_id');
}
}

I many-to-many relationship, get ID of pivot table

I have the following models in a many-to-many relationship:
class Event extends Model
{
public function positions() {
return $this->belongsToMany(Position::class, 'position_events');
}
}
class Position extends Model
{
public function events() {
return $this->belongsToMany(Event::class, 'position_events');
}
}
class PositionEvent extends Model
{
public function position() {
return $this->hasOne(Position::class, 'id', 'position_id');
}
public function event() {
return $this->hasOne(Event::class, 'id', 'event_id');
}
}
The position_events table looks like:
id | event_id | position_id
If $event is an instance of Event, I can get the related positions as:
$event->positions;
This gives me something like the following for each related Position:
{"id":4,"name":"Striker","created_at":"2019-04-02 16:19:57","updated_at":"2019-04-02 16:19:57","pivot":{"event_id":27,"position_id":4}}
Notice the pivot element. It only has event_id and position_id as properties, these are columns from the position_events table. How do I get it to have the id column from that table as well?
Have you tried using withPivot(), for example:
$this->belongsToMany(Position::class, 'position_events')->withPivot('id');

How to retrieve details of second level tables in laravel relationships

I have 3 tables
bank(id, title),
employee(id, name, bank_id),
payroll(id, employee_id, salary).
Now I want to retrieve bank title of employee_id in payroll table.
I have set model relationships
class Bank extends Model
{
public function employees()
{
return $this->hasMany('App\Employee');
}
}
class Employee extends Model
{
public function bank()
{
return $this->belongsTo('App\Bank');
}
public function payrolls()
{
return $this->hasMany('App\Payroll');
}
}
class Payroll extends Model
{
public function employee()
{
return $this->belongsTo('App\Employee');
}
}
I have tried to retrieve using $payroll->employee->bank->title. But it did not help me
Sorry it was my mistake. some employee ids are not referencing bank. That was why I got error.
I resolved the issue by using isset method to verify reference value set or not.
Thanks.
try to change your code a little bit and try again:
public function bank()
{
return $this->hasOne('App\Bank');
}
Read Laravel Official Documentation
/** We can define the inverse of a hasOne relationship using the belongsTo method: **/

BelongsToMany with one or vice versa relationship

I'm using Laravel and Eloquent.
I have a courses table and a Pivot table that holds the related courses.
My pivot table named relatedCourses has 2 columns, course1 & course2.
In the above example, Course ID 5 is related with Course ID 7.
$data["course"] = course::where("isActive",1)->with('related')->find(5);
This works and brings ID 7 as related.
If i try
$data["course"] = course::where("isActive",1)->with('related')->find(7) it should bring ID 5 as related, this is what i'm trying to achieve.
My code is like this in the model :
class course extends Model
{
public function category()
{
return $this->hasOne('App\courseCategory',"categoryId");
}
public function related()
{
return $this->belongsToMany('App\Models\course', 'relatedCourses', 'course1', 'course2');
}
}
You can define two relationships for this query.
class course extends Model
{
public function category()
{
return $this->hasOne('App\courseCategory',"categoryId");
}
public function relatedCourses()
{
return $this->belongsToMany('App\Models\Course', 'relatedCourses', 'course1', 'course2');
}
public function originalCourses()
{
return $this->belongsToMany('App\Models\Course', 'relatedCourses', 'course2', 'course1');
}
}
Then you can query your relations,
$data["course"] = course::where("isActive",1)->with('relatedCourses')->find(5);
and
$data["course"] = course::where("isActive",1)->with('originalCourses')->find(7);
To merge both relations you can do like this
$course = course::where("isActive",1)->with('originalCourses', 'relatedCourses')->get();
Hope this will help you.

Laravel BelongsToMany with two pivot table

I have the following table structure:
products
id
product_formats
id
product_id
product_prices
id
product_format_id
market_id
markets
id
A product can have multiple formats, with each having their own price which belongs in a different market. How can I retrieve the list of Markets from the Product model?
I used to have a single pivot table, however now I have two pivot.
class Product extends Model
{
public function markets()
{
return $this->belongsToMany(Market::class);
}
}
Update
To get the result I want, I did the following:
public function markets()
{
return Market::whereIn('id', $this->prices()->distinct()->pluck('market_id')->toArray());
}
However, I'm wondering if there's a way to accomplish this via a relationship.
You need to build relationships in models.
ProductModel:
public function productFormats()
{
return $this->belongTo(ProductFormatsModel::class);
}
ProductFormatsModel:
public function productPrices()
{
return $this->belongTo(ProductPricesModel::class);
}
ProductPricesModel:
public function markets()
{
return $this->hasOne(MarketsModel::class);
}
in Controller:
foreach($product->productFormats as $productFormat)
{
foreach($productFormat->productPrices as $productPrice)
{
var_dump($productPrice->markets);
}
}
For unique markets
in ProductModel:
public function productPrices()
{
return $this->hasManyThrough(
'App\ProductPricesModel',
'App\ProductFormatsModel',
'product_id',
'product_format_id'
'id',
'id'
);
}
in Controller
foreach($product->productPrices as $productPrice)
{
var_dump($productPrice->markets)
}

Resources