【问题标题】:Laravel Adding One-To-Many on a Pivot tableLaravel 在数据透视表上添加一对多
【发布时间】:2014-10-31 06:14:10
【问题描述】:

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

我有以下结构

我们有 Jobs,Staff 被分配到哪个 Jobs,并且对于这些分配中的每一个,我们都需要存储一些数据 - 类似但不太像日志数据。我们还需要为每个分配存储枢轴特定数据,例如工资率和状态,因此我们将这些存储在枢轴中

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

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_staff。

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

但没有成功..

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

谢谢 西里尔

【问题讨论】:

    标签: php laravel


    【解决方案1】:

    你需要考虑这个:

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

    【讨论】:

    • 感谢您的详细回复。经过一些调整以适应实际实现的复杂性,我得到了这个工作,但这是一个巨大的帮助!谢谢
    • 在这种情况下你会如何加载事件?
    • 当你写信时:$jobStaff = JobStaff::for($job, $staff)->first(); 我猜你的意思是$jobStaff = JobStaff::forThe($job, $staff)->first();
    猜你喜欢
    • 2018-04-03
    • 1970-01-01
    • 1970-01-01
    • 2017-04-11
    • 1970-01-01
    • 1970-01-01
    • 2019-11-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多