为了账号安全,请及时绑定邮箱和手机立即绑定

在 belonsToMany 关系上使用 withPivot 时限制检索的列

在 belonsToMany 关系上使用 withPivot 时限制检索的列

PHP
米脂 2023-04-28 17:24:01
我有一个名为 Shifts 的模型,它与 shift_employee 表具有 belongsToMany 关系,该表充当数据透视表来记录员工的轮班申请。我还有一个范围,以便我可以返回带有移位对象的应用程序。这是我的 Shift 模型的一部分:class Shift extends Model{    //    use SoftDeletes;    use \App\Http\Traits\UsesUuid;    protected $guarded = [];    public function applications()    {        return $this->belongsToMany(Employee::class, 'shift_employee')->as('application')->withTimestamps()->withPivot('shortlisted');    }...    public function scopeWithApplications($query)    {        $query->with('applications');    }...}我的 shift_employee 数据透视表非常简单,结构如下所示。我有一个额外的字段来确定应用程序是否已入围:        Schema::create('shift_employee', function (Blueprint $table) {        $table->primary(['employee_id', 'shift_id']);        $table->uuid('employee_id');        $table->uuid('shift_id');        $table->boolean('shortlisted')->default(false);        $table->timestamps();        $table->foreign('employee_id')            ->references('id')            ->on('employees');        $table->foreign('shift_id')            ->references('id')            ->on('shifts')            ->onDelete('cascade');        });下面是我用于检索班次信息的 API show 函数:public function show($id){    $shift = Shift::where('id', $id)        ->with...()        ->withApplications()        ->with...()        ->first();    return response([        'shift' => $shift,    ]);}这是我得到的回应:"shift": {    "id": "2b91f55b-c0ff-4bdb-abc4-02604ba6a161",    "some_field": "some_value",    ...    "applications": [        {            some_field: "some_value",            ...            application: {                shift_id: "2b91f55b-c0ff-4bdb-abc4-02604ba6a161",                employee_id: "some_uuid",                created_at: ...,                updated_at: ...,                shortlisted: 0            }        },        {        ...        }    ]...}我想要做的是用数据透视表中的字段“入围”替换整个“应用程序”内部对象,这样它看起来像这样:我怎样才能做到这一点?理想情况下,雄辩地调用 withPivot 之类的东西,但不包括其他字段并且不返回对象。我在文档中找不到它,但是否存在类似的东西?
查看完整描述

3 回答

?
饮歌长啸

TA贡献1951条经验 获得超3个赞

我认为最直接的方法是使用数据透视模型基于数据透视表建立独立关系:


class ShiftEmployee extends Pivot

{

    protected $table='shift_employee';

现在是 Shift 模型中的新关系:


class Shift extends Model

{

    public function shortlistedApplications()

    {

        return $this->hasMany(ShiftEmployee::class,'shift_id');

    }

 public function scopeWithShortlistedApplications($query)

    {

        $query->with('shortlistedApplications:shift_id,shortlisted');

    }

}

现在这个新范围将带来你想要的数据


查看完整回答
反对 回复 2023-04-28
?
当年话下

TA贡献1890条经验 获得超9个赞

我认为你需要的是只加载shortlisted你的员工应用程序的属性scopeWithApllications:


public function scopeWithApplications($query)

{

    $query->with('applications.application:id,shortlisted');

}

这仍然会返回一个Application实例作为关系,但只会加载它的shortlisted属性。然后,在检索之后,您可以映射您的集合,以便将应用程序的属性合并到您的员工(如果这真的很重要)。但就数据短缺而言,这可以解决问题。


查看完整回答
反对 回复 2023-04-28
?
呼如林

TA贡献1798条经验 获得超3个赞

在您的应用程序模型中使用 withPivot 方法。像这样:


public function applications(){

return $this->belongsToMany('App\Application')

    ->withPivot('shortlisted')

    ->withTimestamps();}

查看完整回答
反对 回复 2023-04-28
  • 3 回答
  • 0 关注
  • 139 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信