我在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;