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

时间:2014-09-06 12:37:12

标签: php laravel

我在尝试将一对多关系添加到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'的第三个表,它将存储工作人员分配所发生的所有事件的日志,因此这些事件不是特定于员工或工作模型,而是将工作人员分配到工作岗位。举个例子,一些事件可能是

  • '抵达现场'
  • 'Clocked In'
  • '休息'
  • 'Clocked Out'
  • '左侧网站'

依此类推..所以job_staff的数据透视表有很多事件,一个事件属于一个job_staff。

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

的功能

但没有成功..

非常感谢任何指示/想法!

感谢 西里尔

1 个答案:

答案 0 :(得分:4)

你需要考虑这个:

// 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;