且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在Laravel中的数据透视表中添加其他列关系

更新时间:2023-12-01 14:03:46

自定义中间表模型

要解决您的问题,应考虑在 belongsToMany 方法上使用-> using()方法.

此链接中的定义自定义中间表模型"小节对此进行了简要描述. eloquent-relationships#many-to-many

基本上,您将为数据透视表创建一个模型,以便可以为其定义其他关系.

由于Laravel仍会为您处理关系,因此您仍然可以按照现在的方式从Blade和Controllers访问数据.但是,您可以使用-> pivot 访问数据透视表,并且您已经告知laravel为数据透视表使用模型,您还可以访问该模型中所有关系定义的函数.>

示例:

员工

  class员工扩展模型{保护$ fillable = ['name'];公共功能emails(){返回$ this-> belongsToMany('App \ Email')->使用('App \ PivotModel');}} 

电子邮件

 类电子邮件扩展模型{保护$ fillable = ['用户名'];公共职能雇员(){返回$ this-> belongsToMany('App \ Employee')->使用('App \ PivotModel');}} 

PivotModel

  class EmailEmployee扩展了Pivot{公共函数AssignedBy(){返回$ this-> belongsTo('App \ Employee','assigned_by');}} 

请确保在数据透视表模型而非模型上扩展数据透视表

现在您可以这样做:

  $ user-> emails()-> first()-> pivot-> assignedBy 

-> first()的原因是您有很多对很多,这意味着您将获得分配给用户的电子邮件的集合.您通常会遍历它们,但对于本示例,只需选择第一个即可.

如果只需要列值而不是关系值,则添加-> withPivot('assigned_by'),这将允许您直接访问该值.

如果您要审核分配的时间,那么如果数据透视表包含时间戳,则还可能需要添加-> withTimestamps(),以便您也可以访问它们.

Version: Laravel 5.4

I have 3 Models

Model: Employee

    protected $fillable = ['name'];
    public function emails(){
        return $this->belongsToMany('App\Email')->using('App\EmailEmployee');
    }

Model: Email

    protected $fillable = ['username'];
    public function employees(){
        return $this->belongsToMany('App\Employee')->using('App\EmailEmployee');
    }

Every Employee has many email access and emails allocates to many employees. But I have another column in email_employee table

email_id                    (emails table)
employee_id                 (employees table)
assigned_by                 (employees table)

how to make relation of assigned_by column with employees table

Pivot Model

    use \Illuminate\Database\Eloquent\Relations\Pivot;
    class EmailEmployee extends Pivot{
        public function assignedBy(){
            return $this->belongsTo('App\Employee');
        }
    }

I tried


    $email = Email::find(1);
    dd($email->employee[0]->pivot->assignedBy);

But not working

Custom Intermediate Table Model

To solve your problem, you should look to use the ->using() method on the belongsToMany method.

The subsection "Defining Custom Intermediate Table Models" in this link briefly describes this. eloquent-relationships#many-to-many

You basically create a model for the pivot table so that you can define additional relations to it.

You can still access data from Blade and Controllers the way you are now as Laravel will still deal with the relationship for you. However, you can access the pivot table with ->pivot and as you have told laravel to use a model for the pivot table, you can also access all the relationship defined functions from that model.

Example:

Employee

class Employee extends Model
{
protected $fillable = ['name'];
    public function emails(){
        return $this->belongsToMany('App\Email')
        ->using('App\PivotModel');
    }
}

Email

 class Email extends Model
    {
    protected $fillable = ['username'];
        public function employees(){
            return $this->belongsToMany('App\Employee')
            ->using('App\PivotModel');
        }
    }

PivotModel

class EmailEmployee extends Pivot
{
    public function assignedBy(){
            return $this->belongsTo('App\Employee','assigned_by');
        }
}

Be Sure to extend Pivot on the pivot model and not Model

Now you can just do:

$user->emails()->first()->pivot->assignedBy

The reason for the ->first() is that you have a many to many, meaning that you will be getting a collection of emails assigned to the user. You would normally loop through them but for this example, simply selecting the first will do the same.

If you just want the column value and not the relationship value, then add ->withPivot('assigned_by') which will allow you to access the value directly.

If you are wanting to audit when the assignment was made, then you may also want to add ->withTimestamps() if your pivot table has timestamps included, so that you can access those too.