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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25700322/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 10:03:13  来源:igfitidea点击:

Laravel Adding One-To-Many on a Pivot table

phplaravel

提问by Cyril Byrne

I am having a problem trying to add a one-to-many relationship to a pivot table in Laravel, maybe its just not possible?

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

I have the following structure

我有以下结构

We have Jobs, which Staff are assigned to, and for each of these assignments we need to store some data - similar but not quite like, log data. We also need to store pivot specific data for each assignment like pay rate and status, so we store these in the pivot

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

So we have a Job Model (i'm keeping these simple)

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

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

A Staff Model

员工模式

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

}

So that works fine and stores the data in the table 'job_staff'

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

But we need now to have a third table called 'job_events' which will store a log of all events which happened for that staff assignment to the job, so these events are not specific to either the staff or the job model, but to the assignment of the staff member to the job. As an example some events could be

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

  • 'Arrived on Site'
  • 'Clocked In'
  • 'Took Break'
  • 'Clocked Out'
  • 'Left Site'
  • '到达现场'
  • '打卡'
  • '休息'
  • '停工'
  • '左站点'

and so on.. So the pivot table of job_staff has many events, and an event belongs to one job_staff.

等等..所以job_staff的pivot表有很多事件,一个事件属于一个job_staff。

I'm assuming I need a pivot model for the job_staff table, and as such I've been trying to implement something like - https://github.com/laravel/framework/issues/2093#issuecomment-39154456

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

but with no success..

但没有成功..

Would appreciate any pointers/ideas!

将不胜感激任何指针/想法!

thanks Cyril

谢谢西里尔

回答by Jarek Tkaczyk

You need to consider this:

你需要考虑这个:

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

This is due to the fact, that Pivotis instantiated with a few arguments, creating relation context.

这是由于这样一个事实,即Pivot使用一些参数实例化,创建关系上下文。

You have more control using Model, but pretty often you will find yourself in a situation, when you'd rather call ->pivoton the related model, so I suggest creating both:

您可以更好地控制使用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');
    }    
}

Additionally I would create below scope in order to do this:

此外,我将创建以下范围以执行此操作:

$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'));
}

So finally you can use it like this:

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

$jobStaff = $staff->jobs->first()->pivot->events;

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