Laravel在数据透视表上添加一对多


Laravel Adding One-To-Many on a Pivot table

我在Laravel中尝试向数据透视表添加一对多关系时遇到问题,也许这是不可能的?

我有以下结构

我们有分配给员工的工作,对于每一项工作,我们都需要存储一些数据——类似但不太像的日志数据。我们还需要为每个任务存储特定于数据透视的数据,如工资率和状态,因此我们将这些数据存储在数据透视中

所以我们有一个工作模型(我保持这些简单)

class Job extends 'Eloquent {
 public function staff() {
       return $this->belongsToMany('Staff')->withPivot('rate', 'status');
    }
}

员工模型

class Staff extends 'Eloquent {
 public function jobs() {
       return $this->belongsToMany('Job')->withPivot('rate', 'status');
    }
}

这样就可以正常工作,并将数据存储在表"job_staff"中

但我们现在需要有一个名为"job_events"的第三个表,它将存储该员工分配到工作中发生的所有事件的日志,因此这些事件不是特定于员工或工作模型的,而是特定于员工分配到该工作的。例如,一些事件可能是

  • '已到达现场'
  • '已打卡'
  • "休息"
  • '打卡下班'
  • '左侧网站'

等等。所以job_staff的透视表有很多事件,一个事件属于一个job_stafff。

我假设我需要一个job_staff表的pivot模型,因此我一直在尝试实现类似于-https://github.com/laravel/framework/issues/2093#issuecomment-39154456

但是没有成功。。

如果有任何建议/想法,我将不胜感激!

谢谢Cyril

您需要考虑以下内容:

// custom pivot model can be accessed only in the context of relation
$jobStaff = $staff->jobs->first()->pivot;
// additional model for the pivot table can be accessed like any other
$jobStaff = JobStaff::whereStaffId($staff)->whereJobId($job)->first();

这是因为Pivot是用几个参数实例化的,创建了关系上下文。

使用Model可以进行更多控制,但通常情况下,您会发现自己处于这样一种情况,即您宁愿在相关模型上调用->pivot,因此我建议同时创建

use Illuminate'Database'Eloquent'Relations'Pivot;
class JobStaffPivot extends Pivot {
    protected $table = 'job_events';
    // eloquent default name would be:
    // protected $table = 'event_job_staff';
    public function events()
    {
        return $this->hasMany('Event', 'assignement_id');
        // eloquent default would be:
        // return $this->hasMany('Event', 'job_staff_id');
    }
}
use Illuminate'Database'Eloquent'Model;
class JobStaff extends Model {
    protected $table = 'job_events';
    public function job()
    {
        return $this->belongsTo('Job');
    }
    public function staff()
    {
        return $this->belongsTo('Staff');
    }
    public function events()
    {
        return $this->hasMany('Event');
    }    
}

此外,为了做到这一点,我将创建以下范围:

$job = 5;
$staff = 10;
$jobStaff = JobStaff::for($job, $staff)->first();
// or
$job = Job::find($someId);
$staff = Staff::find($anotherId);
$jobStaff = JobStaff::forThe($job, $staff)->first();
// JobStaff model
public function scopeForThe($query, $job_id, $staff_id)
{
    if ($job_id instanceof Job) $job_id = $job_id->getKey();
    if ($staff_id instanceof Staff) $staff_id = $staff_id->getKey();
    $query->where(compact('job_id', 'staff_id'));
}

所以最后你可以这样使用它:

$jobStaff = $staff->jobs->first()->pivot->events;
$jobStaff = JobStaff::forThe($job, $staff)->first()->events;